决策树剪枝与成本复杂性参数

机器学习中,决策树是一种常用的分类和回归算法。然而,决策树容易过拟合,导致模型在训练集上表现很好,但在未知数据上泛化能力差。为了防止这种情况,可以采用剪枝技术来控制决策树的复杂度。本文将介绍如何通过调整成本复杂性参数(ccp_alpha)来实现决策树的剪枝,并展示不同参数值对模型性能的影响。

成本复杂性剪枝的原理

成本复杂性剪枝是一种常用的决策树剪枝方法。它通过递归地找到最“弱”的节点来进行剪枝,这个“弱”节点由一个有效的alpha值来表征。在scikit-learn库中,可以通过DecisionTreeClassifier.cost_complexity_pruning_path方法来获取在剪枝过程中每一步的有效alpha值和对应的叶子节点的总不纯度。随着alpha值的增加,剪枝的程度也会增加,从而使得叶子节点的总不纯度增加。

实验过程

首先,使用乳腺癌数据集来训练一个决策树模型。然后,通过cost_complexity_pruning_path方法获取不同alpha值下叶子节点的总不纯度,并绘制出总不纯度与有效alpha值的关系图。从图中可以看出,随着alpha值的增加,更多的树节点被剪枝,从而使得叶子节点的总不纯度增加。

import matplotlib.pyplot as plt from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier # 加载数据集 X, y = load_breast_cancer(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) # 训练决策树模型并获取剪枝路径 clf = DecisionTreeClassifier(random_state=0) path = clf.cost_complexity_pruning_path(X_train, y_train) ccp_alphas, impurities = path.ccp_alphas, path.impurities

接下来,使用不同的有效alpha值来训练决策树模型,并记录下每个模型的节点数量和树的深度。通过绘制节点数量和树深度与alpha值的关系图,可以观察到随着alpha值的增加,树的节点数量和深度都在减少。

# 训练不同alpha值下的决策树模型 clfs = [] for ccp_alpha in ccp_alphas: clf = DecisionTreeClassifier(random_state=0, ccp_alpha=ccp_alpha) clf.fit(X_train, y_train) clfs.append(clf) # 计算每个模型的节点数量和树深度 node_counts = [clf.tree_.node_count for clf in clfs] depth = [clf.tree_.max_depth for clf in clfs] # 绘制节点数量和树深度与alpha值的关系图 fig, ax = plt.subplots(2, 1) ax[0].plot(ccp_alphas, node_counts, marker="o", drawstyle="steps-post") ax[0].set_xlabel("alpha") ax[0].set_ylabel("number of nodes") ax[0].set_title("Number of nodes vs alpha") ax[1].plot(ccp_alphas, depth, marker="o", drawstyle="steps-post") ax[1].set_xlabel("alpha") ax[1].set_ylabel("depth of tree") ax[1].set_title("Depth vs alpha") fig.tight_layout() plt.show()

最后,比较了不同alpha值下模型在训练集和测试集上的准确率。当alpha值设置为0时,模型在训练集上过拟合,准确率达到100%,但在测试集上的准确率只有88%。随着alpha值的增加,更多的树节点被剪枝,从而使得模型在测试集上的泛化能力得到提高。在这个例子中,当alpha值设置为0.015时,测试集上的准确率达到最大值。

# 计算不同alpha值下模型在训练集和测试集上的准确率 train_scores = [clf.score(X_train, y_train) for clf in clfs] test_scores = [clf.score(X_test, y_test) for clf in clfs] # 绘制准确率与alpha值的关系图 fig, ax = plt.subplots() ax.set_xlabel("alpha") ax.set_ylabel("accuracy") ax.set_title("Accuracy vs alpha for training and testing sets") ax.plot(ccp_alphas, train_scores, marker="o", label="train", drawstyle="steps-post") ax.plot(ccp_alphas, test_scores, marker="o", label="test", drawstyle="steps-post") ax.legend() plt.show()
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485