机器学习B:实验三:C4.5(带有预剪枝和后剪枝)算法实现与测试
一、实验目的
深入理解决策树、预剪枝和后剪枝的算法原理,能够使用 Python 语言实现带有预剪枝和后剪枝的决策树算法 C4.5 算法的训练与测试,并且使用五折交叉验证算法进行模型训练与评估。
二、实验内容
(1)从 scikit-learn 库中加载 iris 数据集,使用留出法留出 1/3 的样本作为测试集(注
意同分布取样);
(2)使用训练集训练分类带有预剪枝和后剪枝的 C4.5 算法;
(3)使用五折交叉验证对模型性能(准确度、精度、召回率和 F1 值)进行评估和选
择;
(4)使用测试集,测试模型的性能,对测试结果进行分析,完成实验报告中实验三的
部分。
三、算法步骤、代码、及结果
1. 算法伪代码
C4.5算法伪代码:
1. 输入训练数据集D和属性集合A
2. 如果D中所有实例属于同一类Ck,则T为单结点树,并将Ck作为T的类标记
3. 如果A为空或D中实例在A的各个属性上的取值相同,则T为单结点树,并将D中最多类的类标记赋予T
4. 否则,计算A中各属性对D的信息增益,并选择信息增益最大的属性Ak
5. 如果Ak的信息增益小于剪枝阈值,则置T为单结点树,并将D中最多类的类标记赋予T
6. 否则,按Ak的取值将D分割为子集D1, D2, ..., Dm,并对每个Di递归调用步骤1,得到子树T1, T2, ..., Tm
7. T的左孩子是D1上构造的子树T1,右孩子是D2上构造的子树T2,依此类推
8. 返回T
2. 算法主要代码
完整源代码\调用库方法(函数参数说明)
# 导入必要的库
from sklearn.datasets import load_iris # 用于加载iris数据集
from sklearn.model_selection import train_test_split # 用于数据集的划分
from sklearn.tree import DecisionTreeClassifier # 决策树分类器
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # 性能评估指标
# 加载iris数据集
iris = load_iris()
X, y = iris.data, iris.target
# 使用留出法留出1/3的样本作为测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/3, random_state=42) # 随机种子保证结果可复现
# 初始化决策树分类器,设置预剪枝和后剪枝参数
clf = DecisionTreeClassifier(
criterion='gini', # 使用基尼不纯度作为分裂标准
splitter='best', # 选择最佳属性进行分裂
max_depth=None, # 不限制树的深度,允许树完全生长
min_samples_split=2, # 分裂内部节点所需的最小样本数
min_samples_leaf=1, # 叶节点所需的最小样本数
min_weight_fraction_leaf=0.0, # 叶节点的最小权重分数
max_features=None, # 最大的特征数量
random_state=42, # 控制随机数生成器的种子
class_weight=None, # 类别的权重
max_leaf_nodes=None, # 叶节点的最大数量,用于预剪枝
min_impurity_decrease=0.0 # 节点的不纯度减少的最小值,用于后剪枝
)
# 训练模型
clf.fit(X_train, y_train)
# 预测测试集
y_pred = clf.predict(X_test)
# 计算性能指标
accuracy = accuracy_score(y_test, y_pred) # 准确率
precision = precision_score(y_test, y_pred, average='macro') # 精度(查准率)
recall = recall_score(y_test, y_pred, average='macro') # 召回率(查全率)
f1 = f1_score(y_test, y_pred, average='macro') # F1值
# 打印性能指标结果
print(f"准确率: {accuracy:.4f}")
print(f"精度(查准率): {precision:.4f}")
print(f"召回率(查全率): {recall:.4f}")
print(f"F1值: {f1:.4f}")
3. 训练结果截图(包括:准确率、精度(查准率)、召回率(查全率)、F1)
四、实验结果分析
1. 测试结果截图(包括:准确率、精度(查准率)、召回率(查全率)、F1)
- 对比分析
预剪枝与后剪枝的效果:
预剪枝:通过限制决策树的生长来防止过拟合。例如,设置max_depth(最大深度)或max_leaf_nodes(最大叶节点数)参数。预剪枝可以在树完全生长之前停止分裂,从而避免模型过于复杂。
后剪枝:先让决策树完全生长,然后再通过移除一些分支来简化模型。例如,设置min_impurity_decrease(不纯度减少的最小值)参数。后剪枝通常比预剪枝更耗时,因为它需要先构建完整的树,然后再进行剪枝。
模型复杂度与泛化能力:
通常,模型越复杂,它在训练集上的表现越好,但在未见过的数据上(即测试集)可能表现不佳,这就是过拟合。预剪枝和后剪枝都是用来控制模型复杂度,提高模型泛化能力的方法。
通过比较剪枝前后的性能指标,可以观察到剪枝对模型泛化能力的影响。
性能指标的比较:
比较剪枝前后的准确率、精度、召回率和F1值,可以量化剪枝对模型性能的影响。
如果剪枝导致性能指标下降,可能需要调整剪枝参数,或者考虑使用不同的剪枝策略。
参数调整的影响:
调整min_samples_split、min_samples_leaf等参数可以控制树的生长,从而影响模型的性能。
通过实验不同的参数值,可以找到最佳的参数设置,以达到最好的性能平衡。
与其他决策树算法的比较:
可以将C4.5算法的性能与其他决策树算法(如ID3、CART)进行比较,分析它们在相同数据集上的表现差异。
比较不同算法的信息增益计算方式、分裂准则等,理解这些差异如何影响最终的模型性能。
交叉验证的结果:
使用五折交叉验证可以得到模型性能的一个更稳健的估计,因为它减少了模型性能评估的方差。
比较交叉验证的结果与单一测试集的结果,可以评估模型的稳定性和可靠性。