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

一、实验目的

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

二、实验内容

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

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

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

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

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

  1. 算法伪代码

输入:训练数据集 D,特征集合 A,剪枝参数(如最小样本数)。

输出:决策树模型。

递归生成树:

若 D 全属于同一类别,生成叶节点。

若 A 为空或无法进一步分裂,生成叶节点。

按照信息增益比(Information Gain Ratio)选择分裂属性。

根据分裂属性构建子节点,递归调用。

预剪枝:

在每次分裂时,计算信息增益,若低于设定阈值则停止分裂。

后剪枝:

完全生成树后,移除对测试集无显著贡献的子树。

  1. 算法主要代码

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

import numpy as np

from sklearn.model_selection import train_test_split, cross_validate

from sklearn.tree import DecisionTreeClassifier

from sklearn.datasets import load_iris

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

 

data = load_iris()

X = data.data

y = data.target

 

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

 

clf = DecisionTreeClassifier(criterion='entropy',max_depth=5,min_samples_split=4,min_samples_leaf=2,random_state=42)

 

path = clf.cost_complexity_pruning_path(X_train, y_train)

ccp_alphas = path.ccp_alphas

impurity = path.impurities

 

best_clf = None

best_f1 = 0

for ccp_alpha in ccp_alphas:

    clf_temp = DecisionTreeClassifier(criterion='entropy',max_depth=5,min_samples_split=4,min_samples_leaf=2,ccp_alpha=ccp_alpha)

    clf_temp.fit(X_train, y_train)

   

    y_pred_temp = clf_temp.predict(X_train)

    f1 = f1_score(y_train, y_pred_temp, average='macro')

   

    if f1 > best_f1:

        best_f1 = f1

        best_clf = clf_temp

 

scoring = {

    'accuracy': 'accuracy',

    'precision': make_scorer(precision_score, average='macro'),

    'recall': make_scorer(recall_score, average='macro'),

    'f1': make_scorer(f1_score, average='macro')

}

 

cv_results = cross_validate(best_clf, X_train, y_train, cv=5, scoring=scoring)

 

print(f"\n交叉验证结果:")

print(f"准确率: {cv_results['test_accuracy'].mean():.4f}")

print(f"精度: {cv_results['test_precision'].mean():.4f}")

print(f"召回率: {cv_results['test_recall'].mean():.4f}")

print(f"F1值: {cv_results['test_f1'].mean():.4f}")

 

y_pred_test = best_clf.predict(X_test)

accuracy_test = accuracy_score(y_test, y_pred_test)

precision_test = precision_score(y_test, y_pred_test, average='macro')

recall_test = recall_score(y_test, y_pred_test, average='macro')

f1_test = f1_score(y_test, y_pred_test, average='macro')

 

print(f"\n测试集测试结果")

print(f"准确率: {accuracy_test:.4f}")

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

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

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

调用的库函数

  1. train_test_split

来源:sklearn.model_selection

功能:按比例随机划分训练集和测试集,同时确保类别分布一致(通过 stratify 参数)。

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

参数说明:

X, y:特征数据和目标标签。

test_size=0.33:测试集占比为 1/3。

random_state=42:随机种子,用于保证结果可复现。

stratify=y:按目标标签 y 的分布进行划分,确保训练集和测试集类别分布一致。

  1. DecisionTreeClassifier

来源:sklearn.tree

功能:实现决策树分类器,用于训练模型并支持控制预剪枝。

pre_pruned_tree = DecisionTreeClassifier(criterion='entropy', max_depth=3, min_samples_split=10, random_state=42)

post_pruned_tree = DecisionTreeClassifier(criterion='entropy', random_state=42)

参数说明:

criterion='entropy':选择信息增益作为分裂标准。

max_depth=3:限制树的最大深度(预剪枝参数之一)。

min_samples_split=10:限制分裂所需的最小样本数(预剪枝参数之一)。

random_state=42:随机种子,保证可复现性。

  1. cross_validate

来源:sklearn.model_selection

功能:对模型进行五折交叉验证,评估多个性能指标。

cv_results_pre = cross_validate(pre_pruned_tree, X_train, y_train, cv=5, scoring=scoring)

参数说明:

estimator=pre_pruned_tree:要评估的模型。

X_train, y_train:训练数据。

cv=5:使用五折交叉验证。

scoring=scoring:评估指标(如准确率、精确率、召回率和 F1 值)。

  1. classification_report

来源:sklearn.metrics

功能:生成模型预测结果的详细分类报告,包括准确率、精确率、召回率和 F1 值。

print(classification_report(y_test, y_pred_pre))

参数说明:

y_test:真实标签。

y_pred_pre:模型预测结果。

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

四、实验结果分析

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

从五折交叉验证和测试集的结果来看,模型在交叉验证中的表现较好,准确率、精度、召回率和F1值均较高,分别为0.9600、0.9685、0.9603和0.9605。相比之下,测试集的结果有所下降,准确率、精度、召回率和F1值分别为0.9400、0.9400、0.9400和0.9394。这表明,尽管模型在训练数据上表现良好,但在实际测试数据上的泛化能力略有下降,可能是由于训练集和测试集的数据分布存在差异,导致模型在未见过的数据上性能稍弱。



posted on 2024-12-08 21:45  leapss  阅读(34)  评论(0)    收藏  举报