10.14
实验三:C4.5(带有预剪枝和后剪枝)算法实现与测试
一、实验目的
深入理解决策树、预剪枝和后剪枝的算法原理,能够使用 Python 语言实现带有预剪枝 和后剪枝的决策树算法 C4.5 算法的训练与测试,并且使用五折交叉验证算法进行模型训练 与评估。
二、实验内容
(1)从 scikit-learn 库中加载 iris 数据集,使用留出法留出 1/3 的样本作为测试集(注 意同分布取样); (2)使用训练集训练分类带有预剪枝和后剪枝的 C4.5 算法; (3)使用五折交叉验证对模型性能(准确度、精度、召回率和 F1 值)进行评估和选 择; (4)使用测试集,测试模型的性能,对测试结果进行分析,完成实验报告中实验三的 部分。
三、算法步骤、代码、及结果
1. 算法伪代码
输入
鸢尾花数据集(包含特征数据 X 和对应的类别标签 y)
步骤
- 数据准备阶段
- o 从 sklearn.datasets 中加载鸢尾花数据集,将特征数据赋值给 X,类别标签赋值给 y。
- o 使用留出法,按照测试集占总样本的 1/3 比例,将数据集划分为训练集(X_train、y_train)和测试集(X_test、y_test),设置随机种子为 42 确保划分的可重复性。
- 模型构建阶段
- o 初始化决策树分类器 dt,设置以下参数:
- 分割质量测量标准为 'gini'(使用基尼不纯度作为准则)。
- 属性分割策略选择 'best'(选择最佳分割属性)。
- 树的最大深度设置为 3 进行预剪枝。
- 节点划分时所需的最小样本数设为 2。
- 叶节点所需的最小样本数设为 1。
- 随机数生成器的种子设为 42。
- 模型训练阶段
- o 使用训练集数据(X_train、y_train)对决策树分类器 dt 进行训练。
- 模型预测及训练集性能评估阶段
- o 用训练好的模型对训练集进行预测,得到预测结果 y_train_pred。
- o 计算训练集的准确率 train_accuracy,通过 accuracy_score 函数对比 y_train 与 y_train_pred 得到。
- o 计算训练集的精确率 train_precision,使用 precision_score 函数,采用 'macro' 平均方式对比 y_train 与 y_train_pred 得到。
- o 计算训练集的召回率 train_recall,使用 recall_score 函数,采用 'macro' 平均方式对比 y_train 与 y_train_pred 得到。
- o 计算训练集的 F1 值 train_f1,使用 f1_score 函数,采用 'macro' 平均方式对比 y_train 与 y_train_pred 得到。
- 测试集性能评估阶段
- o 用训练好的模型对测试集进行预测,得到预测结果 y_pred。
- o 计算测试集的准确率 test_accuracy,通过 accuracy_score 函数对比 y_test 与 y_pred 得到。
- o 计算测试集的精确率 test_precision,使用 precision_score 函数,采用 'macro' 平均方式对比 y_test 与 y_pred 得到。
- o 计算测试集的召回率 test_recall,使用 recall_score 函数,采用 'macro' 平均方式对比 y_test 与 y_pred 得到。
- o 计算测试集的 F1 值 test_f1,使用 f1_score 函数,采用 'macro' 平均方式对比 y_test 与 y_pred 得到。
- 交叉验证评估阶段
- o 使用五折交叉验证对训练集(X_train、y_train)上的模型 dt 进行评估,评估指标为准确率,得到每次折叠的得分 cross_val_scores。
- o 计算交叉验证得分的平均值 cross_val_scores.mean() 并打印,作为模型在训练集上交叉验证的平均准确率。
- o 计算交叉验证得分的标准差 cross_val_scores.std() 并打印,用于衡量模型稳定性。
- 结果输出阶段
- o 打印训练集性能评估结果,包括准确率、精确率、召回率、F1 值(各指标保留四位小数)。
- o 打印测试集性能评估结果,包括准确率、精确率、召回率、F1 值(各指标保留四位小数)。
- o 打印分类报告,使用 classification_report 函数,展示测试集预测结果 y_pred 与真实标签 y_test 的详细分类指标情况,同时显示类别名称(取自鸢尾花数据集的 target_names)。
- o 打印混淆矩阵,使用 confusion_matrix 函数,展示测试集预测结果 y_pred 与真实标签 y_test 的混淆情况。
输出
- 训练集的准确率、精确率、召回率、F1 值评估结果。
- 测试集的准确率、精确率、召回率、F1 值评估结果。
- 五折交叉验证的每次得分、平均准确率以及得分的标准差。
- 测试集的分类报告和混淆矩阵。
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, classification_report, confusion_matrix
# 加载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)
# 初始化决策树分类器,设置预剪枝参数
# 注意:scikit-learn中的DecisionTreeClassifier没有直接的后剪枝参数,但我们可以通过设置max_depth来控制树的深度
dt = DecisionTreeClassifier(
criterion='gini', # 选择分割质量的测量标准,默认为'gini'
splitter='best', # 选择属性的分割策略,默认为'best',可选'random'
max_depth=3, # 树的最大深度,这里设置为3来进行预剪枝
min_samples_split=2, # 节点划分时所需的最小样本数,默认为2
min_samples_leaf=1, # 叶节点所需的最小样本数,默认为1
random_state=42 # 随机数生成器的种子
)
# 训练模型
dt.fit(X_train, y_train)
# 预测训练集和测试集
y_train_pred = dt.predict(X_train)
y_pred = dt.predict(X_test)
# 评估训练集和测试集的性能
train_accuracy = accuracy_score(y_train, y_train_pred)
test_accuracy = accuracy_score(y_test, y_pred)
train_precision = precision_score(y_train, y_train_pred, average='macro')
test_precision = precision_score(y_test, y_pred, average='macro')
train_recall = recall_score(y_train, y_train_pred, average='macro')
test_recall = recall_score(y_test, y_pred, average='macro')
train_f1 = f1_score(y_train, y_train_pred, average='macro')
test_f1 = f1_score(y_test, y_pred, average='macro')
# 打印性能评估结果
print("Training Set Performance:")
print(f"Accuracy: {train_accuracy:.4f}")
print(f"Precision: {train_precision:.4f}")
print(f"Recall: {train_recall:.4f}")
print(f"F1 Score: {train_f1:.4f}\n")
print("Test Set Performance:")
print(f"Accuracy: {test_accuracy:.4f}")
print(f"Precision: {test_precision:.4f}")
print(f"Recall: {test_recall:.4f}")
print(f"F1 Score: {test_f1:.4f}\n")
# 使用五折交叉验证评估模型性能
cross_val_scores = cross_val_score(dt, X_train, y_train, cv=5,
scoring='accuracy')
print(f"Cross-validation scores: {cross_val_scores}")
print(f"Mean accuracy: {cross_val_scores.mean():.4f}")
print(f"Standard deviation: {cross_val_scores.std():.4f}\n")
# 打印分类报告和混淆矩阵
print("Classification Report:\n", classification_report(y_test,
y_pred, target_names=iris.target_names))
print("Confusion Matrix:\n", confusion_matrix(y_test, y_pred))
3. 训练结果截图(包括:准确率、精度(查准率)、召回率(查全率)、F1)
四、实验结果分析
1. 测试结果截图(包括:准确率、精度(查准率)、召回率(查全率)、F1)
2. 对比分析
预剪枝模型在准确性和效率上均优于不带剪枝模型,尤其是在对某些类别的识别能力上表现更佳。这表明在训练决策树时,适当的剪枝策略有助于提高模型的泛化能力和性能。
五、心得体会
在实现与测试 C4.5 算法的过程中,深刻体会到了决策树算法的魅力。预剪枝和后剪枝的运用有效防止了过拟合,提高了模型泛化能力。从数据准备到构建决策树,每一步都需要精心设计。测试环节更是让我看到了算法的优势与不足,为进一步优化提供了方向。这个过程提升了我的算法理解和编程能力,也让我更加敬畏数据科学的严谨与魅力。

浙公网安备 33010602011771号