24.12.06

实验三:C4.5(带有预剪枝和后剪枝)算法实现与测试

一、实验目的

深入理解决策树、预剪枝和后剪枝的算法原理,能够使用Python语言实现带有预剪枝 和后剪枝的决策树算法C4.5算法的训练与测试,并且使用五折交叉验证算法进行模型训练 与评估。

 

二、实验内容

(1)从scikit-learn 库中加载 iris 数据集,使用留出法留出 1/3 的样本作为测试集(注 意同分布取样);

(2)使用训练集训练分类带有预剪枝和后剪枝的C4.5算法;

(3)使用五折交叉验证对模型性能(准确度、精度、召回率和 F1 值)进行评估和选 择;

(4)使用测试集,测试模型的性能,对测试结果进行分析,完成实验报告中实验三的 部分。

三、算法步骤、代码、及结果

   1. 算法伪代码

  1. 导入必要的库

   - 从 sklearn.datasets 导入 load_iris

   - 从 sklearn.model_selection 导入 train_test_split 和 cross_val_score

   - 从 sklearn.tree 导入 DecisionTreeClassifier

   - 从 sklearn.metrics 导入 accuracy_score, precision_score, recall_score, f1_score

 

2. 加载数据集并拆分

   - 加载 iris 数据集 (X, y)

   - 使用 train_test_split 将数据集按 2:1 比例分为训练集 (X_train, y_train) 和测试集 (X_test, y_test),确保 stratify=y 以保证标签分布一致

 

3. 定义 C4.5 决策树模型(模拟预剪枝)

   - 初始化 DecisionTreeClassifier

     - max_depth: 设置决策树的最大深度

     - min_samples_split: 设置内部节点划分所需的最小样本数

     - min_samples_leaf: 设置叶节点的最小样本数

 

4. 使用训练集训练模型

   - 使用 X_train 和 y_train 拟合模型

 

5. 五折交叉验证

   - 使用 cross_val_score 对模型进行五折交叉验证,分别计算

     - 准确度

     - 精度

     - 召回率

     - F1 值

   - 记录每个指标的平均值

 

6. 在测试集上评估模型性能

   - 使用 X_test 进行预测,得到预测值 y_pred

   - 计算以下评估指标:

     - 准确度 (accuracy_score)

     - 精度 (precision_score)

     - 召回率 (recall_score)

     - F1 值 (f1_score)

 

7. 分析模型在五折交叉验证和测试集上的性能差异

   2. 算法主要代码

完整源代码\调用库方法(函数参数说明)

from sklearn.datasets import load_iris

from sklearn.model_selection import train_test_split, cross_val_score

from sklearn.tree import DecisionTreeClassifier

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

 

# 1. 加载数据集

iris = load_iris()

X = iris.data

y = iris.target

 

# 2. 数据集拆分:训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, stratify=y, random_state=42)

 

# 3. 初始化决策树模型,模拟 C4.5 预剪枝

model = DecisionTreeClassifier(

    criterion='entropy',  # 使用信息增益率,模拟 C4.5

    max_depth=5,          # 限制最大深度

    min_samples_split=4,  # 每个节点最少样本数

    min_samples_leaf=2    # 叶子节点最少样本数

)

 

# 4. 训练模型

model.fit(X_train, y_train)

 

# 5. 五折交叉验证

accuracy_scores = cross_val_score(model, X_train, y_train, cv=5, scoring='accuracy')

precision_scores = cross_val_score(model, X_train, y_train, cv=5, scoring='precision_macro')

recall_scores = cross_val_score(model, X_train, y_train, cv=5, scoring='recall_macro')

f1_scores = cross_val_score(model, X_train, y_train, cv=5, scoring='f1_macro')

 

print(f"五折交叉验证结果:")

print(f"准确度:{accuracy_scores.mean():.4f}")

print(f"精度:{precision_scores.mean():.4f}")

print(f"召回率:{recall_scores.mean():.4f}")

print(f"F1值:{f1_scores.mean():.4f}")

 

# 6. 在测试集上评估

y_pred = model.predict(X_test)

test_accuracy = accuracy_score(y_test, y_pred)

test_precision = precision_score(y_test, y_pred, average='macro')

test_recall = recall_score(y_test, y_pred, average='macro')

test_f1 = f1_score(y_test, y_pred, average='macro')

 

print(f"测试集性能:")

print(f"准确度:{test_accuracy:.4f}")

print(f"精度:{test_precision:.4f}")

print(f"召回率:{test_recall:.4f}")

1. criterion

  • 作用:指定用于划分的评价准则。
  • 取值
  • 'gini':使用基尼系数(Gini impurity)作为划分标准。
  • 'entropy':使用信息增益(entropy)作为划分标准,类似于 C4.5。
  • 默认值'gini'
  • 作用:指定节点划分策略。
  • 取值
  • 'best':在所有特征中选择最优划分。
  • 'random':在随机特征子集中选择最优划分。
  • 默认值'best'
  • 作用:控制树的最大深度,用于预剪枝,防止过拟合。
  • 取值:正整数或 None
  • None 表示树的深度不限制。
  • 默认值None
  • 作用:控制一个节点分裂所需的最小样本数,用于预剪枝。
  • 取值:整数或浮点数。
  • 如果是整数,表示最小样本数。
  • 如果是浮点数,表示总样本数的某一比例。
  • 默认值2
  • 作用:叶节点上最少样本数,用于预剪枝。
  • 取值:整数或浮点数。
  • 如果是整数,表示叶节点最小样本数。
  • 如果是浮点数,表示叶节点中样本占总样本数的比例。
  • 默认值1
  • 作用:叶节点中样本权重的最小占比,用于预剪枝。
  • 取值:浮点数,范围 [0, 0.5]
  • 默认值0.0
  • 作用:用于分裂的最大特征数。
  • 取值
  • 整数:指定的特征数。
  • 浮点数:特征占总特征数的比例。
  • 'auto':选择所有特征。
  • 'sqrt':选择 sqrt(n_features) 个特征。
  • 'log2':选择 log2(n_features) 个特征。
  • None:使用所有特征。
  • 默认值None
  • 作用:控制随机数生成,以保证结果的可重复性。
  • 取值:整数或 None
  • 默认值None
  • 作用:限制最大叶节点数,用于预剪枝。
  • 取值:正整数或 None
  • None 表示不限制叶节点数。
  • 默认值None
  • 作用:控制分裂节点时的最小不纯度下降。
  • 取值:浮点数,范围 >=0
  • 默认值0.0
  • 作用:指定类别权重,用于处理类别不平衡问题。
  • 取值
  • None:不调整类别权重。
  • 'balanced':根据样本数自动调整权重,使每个类别的权重与其样本数成反比。
  • 字典形式:自定义类别权重。
  • 默认值None
  • 作用:用于后剪枝(代价复杂度剪枝)。
  • 取值:非负浮点数。
  • 默认值0.0

2. splitter

3. max_depth

4. min_samples_split

5. min_samples_leaf

6. min_weight_fraction_leaf

7. max_features

8. random_state

9. max_leaf_nodes

10. min_impurity_decrease

11. class_weight

12. ccp_alpha (剪枝参数)

 

 

   3. 训练结果截图(包括:准确率、精度(查准率)、召回率(查全率)、F1)

 

 

 

四、实验结果分析

1. 测试结果截图(包括:准确率、精度(查准率)、召回率(查全率)、F1)

 

 

 

2. 对比分析

1. 准确度 (Accuracy)

五折交叉验证:0.9300

测试集:0.8600

分析:准确度从五折交叉验证的 93% 下降到测试集的 86%,这是一个显著的差距。五折交叉验证是在训练集上进行的,而测试集是新的数据集,因此测试集的表现下降说明模型可能存在一定的过拟合。虽然模型在训练集上表现较好,但在测试集上预测效果有所下降。

2. 精度 (Precision)

五折交叉验证:0.9384

测试集:0.8690

分析:精度从 93.84% 下降到 86.90%。精度度量的是模型预测的正类中有多少是真正的正类,精度下降表明在测试集中,模型的错误正类预测数量有所增加。该结果进一步支持了模型在新数据上的泛化性能不如训练集的结论。

3. 召回率 (Recall)

五折交叉验证:0.9302

测试集:0.8627

分析:召回率从 93.02% 降低到 86.27%。召回率表示在所有正类中,模型识别了多少个正类。召回率下降意味着在测试集上,模型对正类的识别率有所下降。这表明模型在测试集上的泛化性能有一定的不足,导致其无法捕获尽可能多的正类样本。

4. F1 值

五折交叉验证:0.9384

测试集:0.8617

分析:F1 值从 93.84% 下降到 86.17%,表明模型在测试集上整体的分类能力有所减弱。F1 值结合了精度和召回率,下降幅度与精度和召回率的下降幅度一致,进一步验证了测试集上表现的下降。

总结

泛化能力不足:模型在五折交叉验证中的表现优于在测试集上的表现,这表明模型在训练集上可能出现了过拟合,导致泛化到新数据的能力不强。

posted on 2024-12-06 18:18  Daniel350  阅读(34)  评论(0)    收藏  举报