前言
一、决策树简介
(一)决策树结构
(二)决策树构建过程(三要素)
二、信息熵与信息增益
(一)信息熵
(二)信息增益
三、ID3决策树
(一)定义与公式
(二)ID3决策树构建过程
(三)不足之处
四、C4.5决策树
(一)定义与公式
(二)C4.5决策树构建过程
五、CART决策树
(一)CART分类和回归树
(二)CART分类树
1. 定义与公式
2. CART分类树构建过程
(三)CART回归树
1. 定义与公式
2. CART回归树构建过程
(三)CART分类树和回归树的比较
1. 代码展示
2. 可视化展示
六、ID3、C4.5和CART对比
七、案例--泰坦尼克号乘客生存预测
(一)代码实现
(二)结果展示
八、决策树的剪枝
(一)为什么要剪枝
(二)什么是决策树的剪枝
(三)决策树剪枝方法
1. 预剪枝
2. 后剪枝
前言
决策树是一种经典的机器学习算法,广泛应用于分类和回归任务中。它通过构建树形结构来对数据进行分类或预测,具有可解释性强、易于理解和实现等优点。
本文将详细介绍决策树的基本概念、构建过程、不同类型的决策树算法(ID3、C4.5、CART),以及决策树的剪枝技术,并通过一个实际案例(泰坦尼克号生存预测)展示决策树的应用。
一、决策树简介
(一)决策树结构
决策树是一种树形结构,树中每个内部节点表示一个特征上的判断,每个分支代表一个判断结果的输出,每个叶子节点代表一种分类结果。
例如,在一个简单的分类问题中,我们可以通过一系列问题(如“年龄是否大于30?”“收入是否高于5000?”等)来判断一个人是否属于某个类别。
(二)决策树构建过程(三要素)
特征选择:选择有较强分类能力的特征。特征选择是决策树构建的关键步骤之一,不同的决策树算法采用不同的特征选择标准。
决策树的生成:根据选择的特征生成决策树。从根节点开始,递归地选择最优特征并分裂节点,直到满足停止条件(如所有样本属于同一类别、达到最大深度等)。
决策树的剪枝:决策树容易过拟合,即对训练数据拟合得过于完美,导致在新数据上表现不佳。剪枝是缓解过拟合的重要方法,通过移除对整体预测贡献不大的部分子树或节点来提高模型的泛化能力。
二、信息熵与信息增益
(一)信息熵
信息熵(Information Entropy)是信息论中的一个核心概念,由由克劳德·香农在1948年提出。它本质上是对不确定性或信息量的度量。在决策树算法中,信息熵通过计算信息增益来评估特征的分类能力。通过选择信息增益最大的特征进行数据分割,可以有效地降低数据的不确定性,提高决策树的分类性能。信息熵越大,信息的不确定性越大,信息的确定性越小,信息的纯度越低,分类的效果越差。信息熵的计算公式为:
其中,是数据集
的信息熵。
是数据集
中的类别总数。
是第 k 个类别的概率,即
,其中
是第
个类别的样本数,
是数据集
的总样本数。
示例1:计算数据集的信息熵
假设我们有一个数据集 D,其中包含3个类别,样本分布如下:
类别1:5个样本 ;类别2:3个样本;类别3:2个样本,那么总样本数为 ∣D∣=5+3+2=10
计算每个类别的概率:p1=5/10=0.5 p2=3/10=0.3 p3=2/10=0.2
计算 D 的信息熵:
在决策树算法中,信息熵用于评估特征的分类能力。具体来说,信息熵用于计算信息增益(Information Gain),从而选择最优的特征进行数据分割。
(二)信息增益
信息增益(Information Gain, IG)是决策树算法中用于选择最佳分裂属性的一种度量方式。它基于信息论中的熵概念,用来评估通过某个特征对数据集进行分割后所带来的纯度提升或不确定性减少的程度。信息增益的计算公式为:
其中,H(D) 是数据集 D 的经验熵;H(D∣A) 是条件熵,表示在已知特征 A 的条件下数据集 D 的经验条件熵。条件熵的计算公式为:
其中,n 是特征 A 的不同取值个数;Di 是特征 A 取第 i 个值时的数据子集;∣Di∣ 是子集 Di 的样本数;H(Di) 是子集 Di 的信息熵。
示例2:计算信息增益
假设我们有一个数据集 D,包含6个样本,目标变量 Y 有两个类别(A和B),特征 X 有两个取值(α和β)。数据分布如下:
特征 X | 目标 Y |
---|---|
α | A |
α | A |
α | A |
α | B |
β | B |
β | B |
首先,计算数据集 D 的信息熵:类别A的样本数:4;类别B的样本数:2;总样本数:6
计算每个类别的概率:pA=4/6≈0.6667 pB=2/6≈0.3333
计算数据集 D 的信息熵:
计算条件熵 H(D∣X):
在ID3决策树算法中,信息增益用于选择最优的特征进行数据分割。具体步骤如下:
①计算每个特征的信息增益:对于数据集 D 中的每个特征 A,计算其信息增益 IG(D,A)。
②选择信息增益最大的特征:选择信息增益最大的特征 作为当前节点的分裂特征。
③生成子集并递归:根据特征的不同取值,将数据集 D 分成多个子集 Di,并对每个子集递归执行上述步骤,直到满足停止条件(如所有样本属于同一类别、达到最大深度等)。
三、ID3决策树
(一)定义与公式
ID3决策树采用信息增益作为特征选择的标准。信息增益表示通过某个特征对数据集进行分割后所带来的纯度提升或不确定性减少的程度。其计算公式为:
其中,H(D) 是数据集 D 的经验熵,H(D∣A) 是条件熵,表示在已知特征 A 的条件下数据集 D 的经验条件熵。
(二)ID3决策树构建过程
①计算每个特征的信息增益。
②使用信息增益最大的特征将数据集拆分为子集。
③使用该特征(信息增益最大的特征)作为决策树的一个节点。
④若该节点已成功分类(节点中只有一个类的样本)或该节点达到停止生长条件,则停止生长,否则使用剩余特征对子集重复上述(1,2,3)过程。
(三)不足之处
ID3算法基于信息增益计算的方式,会偏向于选择种类多的特征作为分裂依据。
例如,一个特征有10个取值,另一个特征只有2个取值,ID3算法可能会优先选择10个取值的特征,即使它对分类的贡献并不大。
四、C4.5决策树
(一)定义与公式
C4.5决策树采用信息增益率作为特征选择的标准(选择最优特征的指标),以解决ID3算法中信息增益对多值特征的偏好问题,避免了过拟合问题。信息增益率的计算公式为:
信息增益率 = 信息增益 / 特征熵
其中,特征熵是对特征 A 的内在信息的度量,相当于对信息增益进行修正,增加一个惩罚系数。特征取值个数较多是,惩罚系数较小;特征取值个数较少时,惩罚系数较大。惩罚系数:数据集D以特征a作为随机变量的熵的倒数。
(二)C4.5决策树构建过程
C4.5决策树的生成过程与ID3类似,只是在特征选择时调整为基于信息增益率进行特征选择。
五、CART决策树
(一)CART分类和回归树
CART(Classification and Regression Tree)是一种典型的决策树算法,二叉树结构,既可以用于分类问题(生成分类树)又可以用于回归问题(生成回归树)。
(二)CART分类树
1. 定义与公式
CART分类树采用基尼指数作为特征选择的标准。基尼指数表示从数据集中随机抽取两个样本,其类别标记不一致的概率。基尼指数越小,数据集的纯度越高。其计算公式为:
其中,是第k个类别的概率。
注意:①信息增益(ID3)、信息增益率(C4.5)值越大,则说明优先选择该特征
②基尼指数(CART)数值越小,则说明优先选择该特征
2. CART分类树构建过程
CART分类树的生成过程与ID3类似,只是在特征选择时调整为基于基尼指数进行特征选择。
(三)CART回归树
1. 定义与公式
CART回归树采用最小化回归树预测结果的平方误差作为特征选择的标准。CART回归树的平方损失:
2. CART回归树构建过程
①选择一个特征,将该特征的值进行排序,取相邻点计算均值作为待划分点
②根据所有划分点,将数据集分成两部分:R1、R2
③R1 和 R2 两部分的平方损失相加作为该切分点平方损失
④取最小的平方损失的划分点,作为当前特征的划分点
⑤以此计算其他特征的最优划分点、以及该划分点对应的损失值
⑥在所有的特征的划分点中,选择出最小平方损失的划分点,作为当前树的分裂点
(三)CART分类树和回归树的比较
CART 分类树预测输出的是一个离散值,CART 回归树预测输出的是一个连续值
CART 分类树使用基尼指数作为划分、构建树的依据,CART 回归树使用平方损失
分类树使用叶子节点多数类别作为预测类别,回归树则采用叶子节点里均值作为预测输出
1. 代码展示
# 1、导包
import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn.linear_model import LinearRegression# 2、准备数据集
x = np.array(list(range(1, 11))).reshape(-1, 1)
y = np.array([5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05])
# print(x)
# print(y)# 3、实例化模型
# 决策树回归模型,限制最大深度为1
model1 = DecisionTreeRegressor(max_depth=1)
# 决策树回归模型,限制最大深度为3
model2 = DecisionTreeRegressor(max_depth=3)
# 线性回归模型
model3 = LinearRegression()# 4、模型训练
# 使用相同的数据集对不同的模型进行训练
model1.fit(x, y)
model2.fit(x, y)
model3.fit(x, y)# 5、模型预测
# 准备测试数据集,为连续的等差数组
x_test = np.arange(0.0, 10.0, 0.1).reshape(-1, 1)
"""
reshape(-1, 1):将一维数组转为二维列向量,-1:自动计算行数,1:固定列为 1添加之前:x_test.shape # 输出: (100,),100列特征值添加之后:x_test.shape # 输出: (100, 1),100行数据,1列特征值
why?在scikit-learn中,所有模型的fit()和predict()方法都期望输入是一个二维数组,即使只有一维特征所以必须把形状 (n_samples,) 转换为 (n_samples, 1)
"""# 使用训练好的模型对测试数据集进行预测
y_pred1 = model1.predict(x_test)
y_pred2 = model2.predict(x_test)
y_pred3 = model3.predict(x_test)# 6、结果可视化
# 创建图形和轴对象
plt.figure(figsize=(10, 6), dpi=100)
# 绘制原始数据点
plt.scatter(x, y, label='data')# 绘制不同模型预测的结果曲线
plt.plot(x_test, y_pred1, label='max_depth=1')
plt.plot(x_test, y_pred2, label='max_depth=3')
plt.plot(x_test, y_pred3, label='linear')plt.xlabel('data') # 设置x轴标签
plt.ylabel('target') # 设置y轴标签
plt.title('DecisionTreeRegressor') # 设置图形标题
plt.legend() # 添加图例
plt.show() # 显示图形
2. 可视化展示
六、ID3、C4.5和CART对比
算法名称 | 特征选择标准 | 分支方式 | 适用数据类型 | 优点 | 缺点 |
ID3 | 信息增益 | 多分支 | 离散数据 | 简单易实现 | 倾向于选择取值多的特征,容易过拟合 |
C4.5 | 信息增益率 | 多分支 | 离散和连续数据 | 缓解了ID3的不足,可处理连续数据 | 对噪声数据敏感,计算复杂度较高 |
CART | 基尼指数(分类) 平方误差(回归) | 二叉树 | 离散和连续数据 | 可用于分类和回归,计算量小 | 生成的树较深,容易过拟合 |
七、案例--泰坦尼克号乘客生存预测
(一)代码实现
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score, precision_score, recall_score, roc_auc_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report
from sklearn.tree import plot_tree# 读取训练数据
data = pd.read_csv('data/train.csv')
# 查看数据的基本信息
data.info()# 选择特征列和目标列
x = data[['Pclass', 'Sex', 'Age']]
y = data['Survived']# 对Age列进行均值填充,处理缺失值
x['Age'].fillna(x['Age'].mean())# 将分类变量转换为哑变量(One-Hot编码)
x = pd.get_dummies(x)# 划分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)# 初始化决策树模型
model = DecisionTreeClassifier()
# 训练模型
model.fit(x_train, y_train)
# 模型预测
y_pred = model.predict(x_test)
# 打印分类报告,查看模型性能
print(classification_report(y_test, y_pred))# 打印模型的精确率、召回率、F1分数和AUC值
print("模型的精确率为:", precision_score(y_test, y_pred))
print("模型的召回率为:", recall_score(y_test, y_pred))
print("模型的f1分数为:", f1_score(y_test, y_pred))
print("模型的AUC值为:", roc_auc_score(y_test, y_pred))
可视化决策树模型结构
# 可视化决策树模型
plt.figure(figsize=(20, 10))
plot_tree(model, filled=True, feature_names=x.columns,class_names=['Dead', 'Survived'], max_depth=3)
"""model:要可视化的训练好的决策树模型。filled=True:节点以颜色填充,表示不同的类别或值。feature_names=x.columns:使用 x.columns 作为特征名称,显示在树的判断节点上。class_names=['Dead', 'Survived']:设置分类结果的标签名称。max_depth=3:只显示深度为前3层的树结构。
"""
plt.tight_layout()
# 保存决策树图
# plt.savefig('decision_tree.png', dpi=300, bbox_inches='tight')
plt.show()
(二)结果展示
八、决策树的剪枝
(一)为什么要剪枝
决策树剪枝(Pruning)是防止决策树过拟合、提高模型泛化能力的关键技术。当决策树生长得太深、分支太多时,它会过度拟合训练数据中的噪声和细节,导致在未知数据上表现很差。剪枝通过移除对整体预测贡献不大或可能导致过拟合的部分子树或节点来解决这个问题。
(二)什么是决策树的剪枝
剪枝是将决策树中的一些节点或子树删除,将这些节点的父节点作为新的叶子节点,从而简化决策树的结构。剪枝可以分为预剪枝和后剪枝两种方法。
(三)决策树剪枝方法
1. 预剪枝
预剪枝是在决策树生成过程中,对每个节点在划分前先进行估计,若当前节点的划分不能带来决策树泛化性能提升,则停止划分并将当前节点标记为叶节点。
预剪枝的优点是计算效率高,训练快;缺点是可能过早停止,错过重要模式。
2. 后剪枝
后剪枝是先从训练集生成一棵完整的决策树,然后自底向上地对非叶节点进行考察,若将该节点对应的子树替换为叶节点能带来决策树泛化性能提升,则将该子树替换为叶节点。
后剪枝的优点是保留更多有效结构,泛化性能通常更好;缺点是计算开销大。