目录
一、基本流程
一般的,一棵决策树包含一个根结点,若干个内部结点和若干个叶结点;在叶结点给出决策结果,其它结点则对应于一个属性测试;每个结点包含的样本集合根据属性测试的结果被划分到子结点之中。从根节点到每个叶结点的路径都对应一个判定的序列。决策树的基本流程遵循简单且直观的“分而治之”策略。
输入:
训练集:
属性集:
决策树基本算法的递归返回原因:
- 当前结点包含的样本属于同一类别无法划分
- 当前属性集为空或者所有样本在属性上的取值相同无法划分,此时标记为叶结点,并将类别设置为该结点所含样本最多的类别。
- 当前结点包含的样本集合为空无法划分,将其设置为叶结点并将其类别设置为父结点所含样本最多的类别。
二、划分选择
2.1 信息增益
2.1.1 信息熵
信息熵是用于度量样本集合纯度的指标,是对样本不确定性的度量。假定当前样本集合 D 中第 k 类(样本共有 n 个类别)样本具有的比例是 ,则样本 D 的信息熵定义为:
Ent(D) 的值越小,说明 D 的纯度越高。为便于理解,假设样本 D 只分为两类,并设正类概率为 p , 负类概率为 1-p,于是有:
利用 python 绘制该函数图像:
import matplotlib.pyplot as plt
import numpy as np
from numpy.lib.scimath import log2
x = np.arange(0.01, 0.99, 0.01)
y = -x*log2(x)-(1-x)*log2(1-x)
plt.plot(x, y)
plt.show()
得到的函数图像如下:
可以看出,当 p 取值为 0 或 1,也就是样本都属于一个类时,信息熵有最小值。
2.1.2 条件熵
设样本 D 中,联合概率分布为:
条件熵 H(Y|X) 则表示在已知条件 X 下,Y不确定的情况。其定义为给定条件 X 下,Y 的条件概率分布的熵对 X 的数学期望,其公式如下:
当信息熵和条件熵中的概率由数据估计(特别是极大似然估计)得到时,所对应的熵分别称为经验熵和经验条件熵。
2.1.3 信息增益
信息增益表示得知特征 A 的信息而使得类 y 的信息的不确定性减少程度。定义为集合 D 下的经验熵 Ent(D) 与特征 A 在给定时集合 D 和经验条件熵 H(D|A) 的差值:
若离散属性 a 有 V 个可能的取值 ,用 a 来对样本 D 划分可以得到 V 个分支结点,其中第 v 个分支结点包含了 D 所有在属性 a 上取值为
的样本并将其记作
;考虑到不同的分支结点所包含的样本数不同,给分支结点赋予权重
(也就是概率
),则可以计算出根据属性 a 划分时得到的信息增益:
信息增益越大,则说明使用属性 a 划分所获得的纯度提升越大,因此可以通过信息增益来进行决策树的划分属性选择,即选择所有属性中信息增益最大的属性作为当前的根结点。
2.2 增益率
但实际上信息增益对可取值数目较多的属性有所偏好,为了减少这种偏好带来的负面影响,可以通过增益率代替信息增益作为最优属性的选择依据。增益率的定义如下:
其中 IV(a) 称作属性 a 的固有值,其定义如下:
可见当 a 的取值数目越多, IV(a) 通常会越大。
但增益率对取值数目较少的属性有所偏好,因此可以采用先从划分属性中找出信息增益高于平均水准的属性,再从中选择增益率最高的。
2.3 基尼指数
数据集 D 的基尼指数如下定义:
基尼指数反映了从数据集 D 中抽取两个样本时,这两个样本类别不一致的概率,因此基尼指数越小,样本集 D 的纯度越高。
对于属性 a 的基尼指数定义如下:
由此可选择划分后基尼指数最小的属性作为当前的根结点。
ID3 和 C4.5 算法见 ID3 和 C4.5 算法_DaMeng999的博客-CSDN博客
三、剪枝处理
在决策树的训练过程中,为尽可能正确的分类样本,会不断的重复结点划分过程,有时可能导致决策树分支过多,即导致过拟合训练样本,因此可以通过主动剪枝来降低过拟合风险。
决策树的剪枝往往通过极小化决策树整体的损失函数或代价函数来实现。
3.1 损失函数
假设决策树 T 的叶结点个数为 ,t 是树 T 的叶结点之一,则定义该叶结点有
的样本点,其中第 k 类样本点有
个,
为叶结点 t 上的信息熵,
为参数,则决策树的损失函数可以定义如下:
将上述式子等号右边的第一项记为 C(T) ,C(T) 展开如下:
C(T) 表示模型对训练数据的预测误差,代表着模型与训练数据的拟合程度, 意味着模型的复杂度,参数
控制两者之间的影响,较大的参数促使选择比较简单的模型,若参数值为 0 则意味着只考虑模型的拟合程度而不考虑复杂度。
3.2 剪枝策略
剪枝可以分为预剪枝和后剪枝两种策略:
- 预剪枝:在决策树的生成过程中,对每个结点划分前进行估计,若当前结点的划分无法带来决策树泛化性能的提升,则停止划分。
- 后剪枝:先根据训练集生成一棵完整的决策树,然后自底向上地对非叶节点进行考察,若将当前结点标记为叶结点可以带来决策树的泛化性能提升,则将该子树替换为叶结点。
预剪枝和后剪枝的优缺点如下:
优点 | 缺点 | |
---|---|---|
预剪枝 | 降低了过拟合的风险; 减少了决策树的训练开销; | 有些分支的当前划分可能无法带来泛化性能的提升,但在后续划分中可能提高决策树的性能; 基于贪心地禁止分支的展开,可能导致欠拟合 |
后剪枝 | 欠拟合风险较小,泛化性能往往优于预剪枝; | 训练开销打 |
四、连续值和缺失值处理
4.1 连续值处理
由于连续属性的可取值数目不再有限,因此不能根据连续属性的可取值对其划分。
4.1.1 二分法
给定样本集 D 和连续属性 a ,假定 a 在 D 上出现了 n 个不同的取值,将这些值从小到大排序得到 ,基于划分点 t 可将 D 分为子集
和
,前者代表着在属性 a 上取值小于 t 的样本,后者包含在属性 a 上取值大于 t 的样本。
由此,对连续属性 a 可以考察 n-1 个候选划分点集合
可以参考离散属性值一样来考察这些划分点并从中选取最优划分点,例如根据信息增益可得到改造公式如下:
需要注意,若当前结点划分属性为连续属性,该属性还可以做为后代结点的划分属性。
4.2 缺失值处理
缺失值处理需要解决两个问题:
- 如何在属性值缺失的情况下进行划分属性选择
- 给定划分属性,若样本在该属性上的值缺失如何对样本划分
给定训练集 D 和属性 a ,令 表示 D 在属性 a 上没有缺失值的样本子集,对问题1即可根据
来判断属性 a 的优劣,假定 a 有 V 个可取值
,令
表示
中在属性 a 上取值为
的样本子集,
表示
中第 k 类的样本;假定为每个样本 x 赋予一个权重
,且定义:
由此可以将信息增益的计算式推广为:
其中
对于问题2,若样本 x 在划分属性 a 上的取值位置,则将 x 划分到所有的子结点中,且样本权值在属性值 对应的子节点中调整为
,可以理解为将同一样本以不同的概率划分到不同的子结点中去。
五、多变量决策树
决策树中对样本分类意味着找不同类样本之间的分类边界,决策树所形成的分类边界有一个明显的特点即轴平行,也就是分类边界是由若干个与坐标轴平行的分段组成;若真实分类比较复杂,则必须使用很多段的划分才能获得较好的近似,从而构造了一个相对复杂的决策树。
因此可以通过使用斜的划分边界,将决策树模型简化,即所谓的“多变量决策树”;此时非叶结点不再是单独的某个属性,而是属性的一种线性组合,即一个形如 的线性分类器。其中
是属性
的权重,
和 t 可以在该结点所包含的样本集和属性集上学习得到。
归纳算法在寻找最佳分割的方式上有所不同,可以分类如下:
(来自:HHCART An oblique decision tree)
5.1 使用优化技术的归纳算法
第一个主要的斜决策树算法是分类和回归线性树组合,即 CART-LC ,CART-LC使用确定性爬山算法在非终端节点上搜索最佳的斜分割,还进行了一个向后的特征消除过程,在分割过程中删除不相关的特征;CART-LC 不会在每个节点上找到最佳分割,因为采用的贪婪算法,容易陷入局部最小值。
模拟退火决策树(SADT)使用模拟的退火优化算法,它使用随机化,以寻找最佳的分裂。随机化的使用可能会避免陷入∆(I)的局部极大值。 该算法的主要缺点是找到最佳分割需要的时间。
将 CART-LC 和 SADT 结合得到 OC1 算法。使用确定性爬山算法来扰动初始超平面的系数,直到找到局部最大值。然后随机进行超平面扰动,尝试找到一个可以进一步改进的超平面。
5.1.1 OC1 算法
详细内容见:OC1 算法_DaMeng999的博客-CSDN博客
5.2 标准统计的方式
该方法生成决策树的时间通常少于第一种方法,
5.3 基于启发式的树归纳算法
六、sklearn 训练决策树
首先导入数据集:
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
iris = load_iris()
X = iris.data
y = iris.target
对数据集做一个简单的分析:
可以看到所有的鸢尾花被分为 3 种,并转化成数字 0,1,2 来表示,同时样本有 4 种属性,共有 150 个样本。
根据该样本构建一棵决策树并预览该树的代码如下:
tree_clf = DecisionTreeClassifier(max_depth=3)
tree_clf.fit(X, y)
export_graphviz(tree_clf,
out_file="./iris_tree3.dot",
feature_names=iris.feature_names,
class_names=iris.target_names,
rounded=True, filled=True)
得到的决策树模型如下:
samples 属性统计对应的训练实例数量,gini 属性对应其不纯度。
可以输入一组花的数据来对其预测。
print(tree_clf.predict_proba([[4.9, 3. , 1.4, 0.2]]))
决策树很可能过拟合,所以需要对其正则化。在 Scikit-Learn 中,有以下几种正则化方式来控制决策树:
- max_depth:最大深度
- min_samples_split:分裂前节点必须有的最小样本数
- min_samples_leaf:叶结点必须有的最小样本数
- min_weight_fraction_leaf:加权实例总数的占比
- max_leaf_nodes:最大叶结点数量
- max_feaatures:分裂每个结点评估的最大特征数量
六、决策树特点总结
- 决策树归纳是一种构建分类模型的非参数方法,不需要任何先验假设,不假定类和其他属性服从一定的概率分布
- 最佳决策树是 NP 完全问题,许多决策树算法都采用启发式的方法指导假设空间的搜索,如上述的贪心的自顶向下递归划分策略
- 已开发的构建决策树技术不需要昂贵的计算代价,在大规模训练集下也可以快速建立模型。且决策树模型对未知样本分类非常快,最坏情况下的时间复杂度是 O(d) ,d 是决策树的最大深度。
- 相对容易解释,在简单数据集上的准确率可以媲美其他分类算法
- 是学习离散值函数的典型代表,但不能很好的推广到某些布尔问题
- 对于噪声的干扰具有很好的鲁棒性
- 冗余属性不会对决策树的准确率造成不利影响
- 大多数的决策树算法都采用自顶向下的递归划分方法,沿着树向下记录会越来越少,因此对于叶结点代表的类不能做出具有统计意义的判定,所谓的数据碎片问题(可以通过样本数小于某个特定阈值时停止分裂)
- 子树可能在决策树中重复多次