决策树是机器学习中的基本算法,广泛用于分类和回归任务。它们表示基于从数据中学习的规则的模型,通过根据输入特征的值将数据拆分为子集来做出决策。本博客将介绍决策树背后的原理,包括 CART、ID3 和 C4.5 等流行算法,以及它们如何使用信息增益和基尼指数等指标选择特征和分割点
什么是决策树?
决策树可以看作是一种流程图式的结构 , 其中每个内部节点代表基于特征的决策,每个分支代表该决策的结果,每个叶节点代表最终分类或回归结果。
您可以将其视为一系列“如果-那么”规则,这些规则根据特征值对数据进行分类。在分类树中,目标是将数据点分配给不同的类别。在回归树中,目标是预测连续值。
决策树通常被视为白盒模型, 因为它们是可解释的。通过遵循从根节点到叶节点的路径,可以轻松直观地了解决策的制定过程。
决策树的关键概念
1.特征选择
在每个节点上选择正确的特征对于树的准确性和简单性至关重要。决策取决于哪个特征最适合分割数据以最大限度地减少不确定性。不同的算法使用不同的标准来衡量这一点:
- ID3使用信息增益
- C4.5利用信息增益比改进了 ID3
- CART(分类和回归树)使用基尼指数
熵和基尼系数
熵和基尼系数都是用于衡量数据集中无序或不纯的指标。
- 熵由 ID3 和 C4.5 算法使用。它量化了数据集中的不确定性或无序性。熵的公式 H(X)为:
其中 是类i的概率。类分布越多样化,熵就越高。
-
CART 算法使用基尼指数。它表示如果根据数据集中类的分布随机标记随机选择的样本,则随机选择的样本被错误分类的概率。基尼指数的公式为:
较低的基尼系数表示较纯净的节点。
1. ID3 (Iterative Dichotomiser 3)
ID3算法选择提供最大信息增益的特征作为最优特征来划分数据。
- 信息增益(IG衡量的是基于某个特征划分数据后,输出变量不确定性的减少。其计算公式为: 公式为:
其中,H(D)是数据集的熵,H(D∣A)是基于特征 A划分数据后的熵。选择能够最大化信息增益的特征。
2. C4.5
C4.5算法通过解决ID3算法偏向于具有多种可能值特征的问题进行改进。C4.5使用的是信息增益率,它通过将信息增益除以特征值的熵来对增益进行归一化。
- 信息增益比的定义为:
这里n是特征取值个数,D是样本容量,是对应特征取值下样本的数量,其实就是把每个取值的样本数量进行考虑。这通过惩罚那些熵 较高的特征,避免了偏向于拥有许多唯一值的特征。
3. CART (Classification and Regression Trees)
-
CART算法既可以用于分类,也可以用于回归。对于分类任务,它使用基尼指数来衡量特征划分,并选择能最小化基尼不纯度的特征和划分点。
- 基尼指数和熵类似,基尼指数越大,样本集合的不确定性也就越大
-
对于回归任务,CART最小化均方误差(MSE) ,寻找能够减少预测值方差的最优划分
使用CART算法构建的树如下:
假设有K个类,样本属于k的概率为,基尼指数公式如下:
如果集合D根据特征A可以被分成D1,D2两个部分即
在特征A下,集合D的基尼指数定义为:
下面是基尼指数和熵之半和分类误差率的关系:
建立决策树过程
- 根节点创建:首先将所有训练数据视为属于根节点。
- 拆分:根据所选算法(使用信息增益、增益比或基尼指数),找到拆分数据的最佳特征和值。
- 递归:递归地在每个数据子集(子节点)上重复该过程。
- 停止条件:当停止条件满足时停止(例如,所有节点都是纯的,或者没有更多的特征要分割)。
- 修剪(如有必要):为了避免过拟合**,通过去除不提供显著效益的节点来修剪树。
过拟合和剪枝
决策树的一个主要问题是过度拟合。树可能会变得过于复杂,甚至会拟合训练数据中的噪声,从而降低其泛化到新数据的能力。为了解决这个问题:
- 预修剪:根据每个节点的最大深度或最小样本等标准,提前停止生长树。
- 后剪枝:先构建整个树,然后根据验证数据集删除不能提高性能的节点。
使用“sklearn”的示例实现
下面是一个使用CART算法与Python的“sklearn”库中的“decisiontreecclassifier”进行分类的简单示例:
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 加载数据
iris = load_iris()
X = iris.data
y = iris.target
# 划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建决策树,并且使用gini指数划分数据
clf = DecisionTreeClassifier(criterion='gini', max_depth=3, random_state=42)
# 训练模型
clf.fit(X_train, y_train)
# 预测
y_pred = clf.predict(X_test)
# 验证
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')
在这个例子中,我们使用基尼指数来分割数据,并限制树的深度以避免过拟合。
Reference
《统计学习方法第2版》 李航老师