机器学习实战——基于CART决策树实现葡萄酒品质预测(附完整代码和可视化)
关于作者
作者:小白熊
作者简介:精通c#、Halcon、Python、Matlab,擅长机器视觉、机器学习、深度学习、数字图像处理、工业检测识别定位、用户界面设计、目标检测、图像分类、姿态识别、人脸识别、语义分割、路径规划、智能优化算法、大数据分析、各类算法融合创新等等。
联系邮箱:xbx3144@163.com
科研辅导、知识付费答疑、个性化定制以及其他合作需求请联系作者~
1 引言
随着机器学习技术的发展,决策树作为一种简单而强大的算法,在许多领域得到了广泛的应用。本文将通过一个具体的案例——使用决策树模型预测葡萄酒品质,来详细介绍决策树的工作原理、构建过程以及评估方法。我们将利用Python编程语言及其相关的科学计算库(如NumPy、Pandas)和机器学习库(如Scikit-learn)来进行数据分析与模型训练。
2 决策树模型理论介绍
决策树是一种监督学习方法,它可以用于解决分类和回归问题。其基本思想是通过一系列的条件判断(即决策节点),最终到达某个结论(即叶子节点)。每个内部节点代表一个属性上的测试,每个分支代表一个测试结果,而每个叶子节点则保存了一个类别标签或数值输出。决策树具有良好的可解释性,使得非专业用户也能理解模型的决策过程。
2.1 决策树主要组成部分
- 根节点:没有进入条件,是所有决策路径的起点;
- 内部节点:表示一个测试条件;
- 分支:从一个节点到另一个节点的有向边,表示测试条件的结果;
- 叶子节点:包含类别标签或数值输出,是决策路径的终点。
2.2 关键步骤
- 选择最佳分裂属性:通过计算信息增益(Information Gain)、基尼不纯度(Gini Impurity)等指标来确定哪个属性能够提供最好的数据分割。
- 递归地创建子树:对每个子节点重复上述过程,直到满足停止条件(如达到最大深度、节点内数据量小于阈值等)。
- 剪枝:为了防止过拟合,可以采用预剪枝或后剪枝策略减少树的复杂度。
2.3 常用的决策树算法
- ID3:基于信息增益进行特征选择。
- C4.5:改进了ID3,使用信息增益比作为分裂标准,并支持剪枝。
- CART:既可以用于分类也可以用于回归,使用基尼不纯度作为分裂标准。
2.4 参数介绍
在构建决策树模型时,有许多重要的参数需要设置以控制模型的行为。这些参数直接影响着决策树的结构和性能。以下是本案例中使用的一些主要参数及其作用:
- criterion:定义了分裂的质量标准,常见的选项有’gini’(基尼不纯度)和’entropy’(信息熵)。
- splitter:决定了如何选择分割点,可以是’best’(选择最优分割点)或’random’(随机选择分割点)。
- max_depth:树的最大深度,用于限制模型的复杂度,防止过拟合。
- min_samples_split:分割内部节点所需的最小样本数,同样用于控制模型复杂度。
- min_samples_leaf:叶节点所需的最小样本数,确保每个叶子节点有足够的代表性。
- min_weight_fraction_leaf:叶节点所需的最小加权分数,用于处理不平衡数据集。
- max_features:寻找最佳分割时要考虑的特征数量,可以提高模型训练速度。
- random_state:随机种子,保证每次运行结果的一致性。
- max_leaf_nodes:最大叶节点数,进一步限制树的大小。
- class_weight:类别的权重,对于不平衡数据集非常有用。
- ccp_alpha:复杂度参数,用于剪枝,减少过拟合的风险。
3 代码解析
3.1 数据准备
在开始构建模型之前,首先需要准备好数据。本案例使用的是sklearn.datasets中的葡萄酒数据集,这是一个经典的多分类任务数据集,包含了不同类型的葡萄酒及其化学成分信息。
from sklearn.datasets import load_wine
# 加载数据集
data = load_wine()
# 数据转换
df = pd.DataFrame(data.data, columns=data.feature_names)
df['Target'] = data.target
# 缺失值检测
missing_values = df.isnull().sum()
print("缺失值检测结果:\n", missing_values)
这段代码首先加载了葡萄酒数据集,并将其转换为Pandas DataFrame格式,方便后续的数据处理。接着,我们检查了数据集中是否存在缺失值,确保数据的完整性。
3.2 特征工程
在实际应用中,原始数据往往需要经过一定的预处理才能更好地服务于模型训练。在这个案例中,我们将对数据进行标准化处理,以消除特征之间量纲差异的影响。
from sklearn.preprocessing import StandardScaler
# 数据提取
X = df.drop('Target', axis=1)
y = df['Target']
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
这里,我们使用StandardScaler对特征进行了标准化,使得每个特征的均值为0,方差为1。这一步骤有助于提升某些类型模型的性能,尤其是那些对输入数据尺度敏感的模型。
3.3 模型训练
有了准备好的数据,接下来就可以构建并训练我们的决策树模型了。我们将使用DecisionTreeClassifier类来创建模型,并通过交叉验证来评估模型的泛化能力。
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from sklearn.tree import DecisionTreeClassifier
# 划分训练集和验证集
X_train, X_val, y_train, y_val = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# 构建模型
model = DecisionTreeClassifier(
criterion='gini', # 分裂的质量标准
splitter='best', # 决定如何选择分割点
max_depth=5, # 树的最大深度
min_samples_split=2, # 分割内部节点所需的最小样本数
min_samples_leaf=1, # 叶节点所需的最小样本数
min_weight_fraction_leaf=0.0, # 叶节点所需的最小加权分数
max_features=None, # 寻找最佳分割时要考虑的特征数量
random_state=42, # 随机种子
max_leaf_nodes=None, # 最大叶节点数
class_weight=None, # 类别的权重
ccp_alpha=0.0 # 复杂度参数,用于剪枝
)
# 十折交叉验证
kf = KFold(n_splits=10, shuffle=True, random_state=42)
cv_scores = cross_val_score(model, X_train, y_train, cv=kf, scoring='accuracy')
print(f"平均准确率: {np.mean(cv_scores)}")
# 训练模型
model.fit(X_train, y_train)
在这段代码中,我们首先将数据集划分为训练集和验证集,然后构建了一个决策树分类器。通过十折交叉验证,我们可以得到模型在训练集上的平均准确率,从而评估模型的稳定性和泛化能力。最后,我们使用训练集对模型进行了训练。
3.4 模型评估
模型训练完成后,我们需要对其进行评估,以了解其在未见数据上的表现。常用的评估指标包括准确率、精确率、召回率和F1分数。
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
# 模型预测
y_val_pred = model.predict(X_val)
# 计算混淆矩阵
conf_matrix = confusion_matrix(y_val, y_val_pred)
# 计算分类评估指标
accuracy_val = accuracy_score(y_val, y_val_pred)
precision_val = precision_score(y_val, y_val_pred, average='weighted')
recall_val = recall_score(y_val, y_val_pred, average='weighted')
f1_val = f1_score(y_val, y_val_pred, average='weighted')
print(f"准确率: {accuracy_val}")
print(f"精确率: {precision_val}")
print(f"召回率: {recall_val}")
print(f"F1分数: {f1_val}")
这段代码首先使用训练好的模型对验证集进行预测,然后计算了混淆矩阵及各类评估指标。混淆矩阵是一个重要的工具,可以帮助我们直观地看到模型在各个类别上的表现情况。而准确率、精确率、召回率和F1分数则提供了更具体的量化评价。
3.5 结果可视化
为了更直观地展示模型的性能,我们可以通过绘制混淆矩阵热力图和决策树图来帮助理解和解释模型。
import seaborn as sns
import matplotlib.pyplot as plt
from graphviz import Source
# 可视化混淆矩阵
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=data.target_names, yticklabels=data.target_names)
plt.title(f'混淆矩阵')
plt.xlabel("预测值")
plt.ylabel("真实值")
plt.show()
# 绘制决策树图
graph = Source(export_graphviz(model, out_file=None,
feature_names=data.feature_names,
class_names=data.target_names,
filled=True, rounded=True,
special_characters=True))
graph.format = 'png'
graph.render('decision_tree', view=True)
通过上述代码,我们首先使用Seaborn库绘制了混淆矩阵的热力图,然后使用Graphviz库生成了决策树的图形化表示。这些可视化工具不仅使结果更加直观易懂,还能够帮助我们发现模型潜在的问题和改进方向。
4 完整代码
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
import seaborn as sns
from sklearn.datasets import load_wine
import matplotlib.pyplot as plt
import warnings
from graphviz import Source
warnings.filterwarnings("ignore")
# 设置中文字体为SimHei
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 加载数据集
data = load_wine()
# 数据转换
df = pd.DataFrame(data.data, columns=data.feature_names)
df['Target'] = data.target
# 缺失值检测
missing_values = df.isnull().sum()
print("缺失值检测结果:\n", missing_values)
# 数据提取
X = df.drop('Target', axis=1)
y = df['Target']
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 划分训练集和验证集
X_train, X_val, y_train, y_val = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# 构建模型
model = DecisionTreeClassifier(
criterion='gini', # 分裂的质量标准
splitter='best', # 决定如何选择分割点
max_depth=5, # 树的最大深度
min_samples_split=2, # 分割内部节点所需的最小样本数
min_samples_leaf=1, # 叶节点所需的最小样本数
min_weight_fraction_leaf=0.0, # 叶节点所需的最小加权分数
max_features=None, # 寻找最佳分割时要考虑的特征数量
random_state=42, # 随机种子
max_leaf_nodes=None, # 最大叶节点数
class_weight=None, # 类别的权重
ccp_alpha=0.0 # 复杂度参数,用于剪枝
)
# 十折交叉验证
kf = KFold(n_splits=10, shuffle=True, random_state=42)
cv_scores = cross_val_score(model, X_train, y_train, cv=kf, scoring='accuracy')
print(f"平均准确率: {np.mean(cv_scores)}")
# 训练模型
model.fit(X_train, y_train)
# 模型预测
y_val_pred = model.predict(X_val)
# 计算混淆矩阵
conf_matrix = confusion_matrix(y_val, y_val_pred)
# 计算分类评估指标
accuracy_val = accuracy_score(y_val, y_val_pred)
precision_val = precision_score(y_val, y_val_pred, average='weighted')
recall_val = recall_score(y_val, y_val_pred, average='weighted')
f1_val = f1_score(y_val, y_val_pred, average='weighted')
print(f"准确率: {accuracy_val}")
print(f"精确率: {precision_val}")
print(f"召回率: {recall_val}")
print(f"F1分数: {f1_val}")
# 可视化混淆矩阵
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=data.target_names, yticklabels=data.target_names)
plt.title(f'混淆矩阵')
plt.xlabel("预测值")
plt.ylabel("真实值")
plt.show()
# 绘制决策树图
graph = Source(export_graphviz(model, out_file=None,
feature_names=data.feature_names,
class_names=data.target_names,
filled=True, rounded=True,
special_characters=True))
graph.format = 'png'
graph.render('decision_tree', view=True)
5 结论
通过本次实践,我们详细介绍了决策树模型的基本理论、构建流程以及评估方法,并通过一个具体的案例展示了如何利用Python及其相关库来实现这一过程。决策树作为一种强大的机器学习工具,不仅易于理解和解释,而且在处理分类和回归问题上都表现出色。
标签:val,模型,CART,score,可视化,import,节点,决策树 From: https://blog.csdn.net/m0_59197405/article/details/143992514