机器学习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

 

 

  1. 对比分析

预剪枝与后剪枝的效果

预剪枝:通过限制决策树的生长来防止过拟合。例如,设置max_depth(最大深度)或max_leaf_nodes(最大叶节点数)参数。预剪枝可以在树完全生长之前停止分裂,从而避免模型过于复杂。

后剪枝:先让决策树完全生长,然后再通过移除一些分支来简化模型。例如,设置min_impurity_decrease(不纯度减少的最小值)参数。后剪枝通常比预剪枝更耗时,因为它需要先构建完整的树,然后再进行剪枝。

模型复杂度与泛化能力

通常,模型越复杂,它在训练集上的表现越好,但在未见过的数据上(即测试集)可能表现不佳,这就是过拟合。预剪枝和后剪枝都是用来控制模型复杂度,提高模型泛化能力的方法。

通过比较剪枝前后的性能指标,可以观察到剪枝对模型泛化能力的影响。

 

性能指标的比较

 

比较剪枝前后的准确率、精度、召回率和F1值,可以量化剪枝对模型性能的影响。

如果剪枝导致性能指标下降,可能需要调整剪枝参数,或者考虑使用不同的剪枝策略。

 

参数调整的影响

 

调整min_samples_split、min_samples_leaf等参数可以控制树的生长,从而影响模型的性能。

通过实验不同的参数值,可以找到最佳的参数设置,以达到最好的性能平衡。

 

与其他决策树算法的比较

 

可以将C4.5算法的性能与其他决策树算法(如ID3、CART)进行比较,分析它们在相同数据集上的表现差异。

比较不同算法的信息增益计算方式、分裂准则等,理解这些差异如何影响最终的模型性能。

 

交叉验证的结果

 

使用五折交叉验证可以得到模型性能的一个更稳健的估计,因为它减少了模型性能评估的方差。

比较交叉验证的结果与单一测试集的结果,可以评估模型的稳定性和可靠性。

 

posted @ 2024-11-27 10:57  痛苦代码源  阅读(13)  评论(0编辑  收藏  举报