d2m-3-决策树
基本流程
输入:训练集 D = { ( x 1 , y 1 ) , . . . , ( x n , y n ) } D=\{(x_1, y_1), ..., (x_n, y_n)\} D={(x1,y1),...,(xn,yn)}, 特征集 A = { a 1 , . . , a m } A=\{a_1, .., a_m\} A={a1,..,am}
过程:函数TreeGenerate(D, A)
- 生成节点node
- if D中样本完全属于同一类别C,then 将node标记为C类叶节点;return end if
- if A空 or D中样本在A上取值相同 then 将node标记为D中样本数最多的类的叶节点;return end if
- 从A中选择最优划分属性
a
∗
a_*
a∗,怎么选呢,如下
- 遍历A,计算划分准则来选择
- for
a
∗
a_*
a∗的每一个值
a
∗
v
a_*^v
a∗v do
- 为node生成一个分支,令 D v D_v Dv表示D中在 a ∗ a_* a∗上取值为 a ∗ v a_*^v a∗v的样本子集
- if D v D_v Dv为空,then 将node标记为D中样本数最多的类的叶节点;return
- else 以TreeGenerate(
D
v
D_v
Dv, A-{a_*})为分支节点 end if
end for
输出:以node为根节点的一颗决策树
理论部分
ID3
算法步骤
1. 初始化信息增益阈值$\epsilon$
2. 判断样本是否为同一类输出$D_i$
1. 如果是,则输出单节点树$T$,输出类别为$D_i$
2. 如果不是,则判断特征集$A$是否为空
1. 如果是空,则输出单节点树$T$, 输出类别为类别众数对应那个类别
2. 如果不是,则从特征集$A$中遍历每个特征$A_i$,计算$H(D)-H(D|A)$,选取信息增益最大的那个特征$A_g$作为分裂点
1. 如果信息增益小与$\epsilon$,则输出当前树$T_i$,输出类别为类别众数对应那个类别
2. 如果不是,则将其分裂,并遍历所有子节点,令$D=D_i, A=A-\{A_g\}$,重复上述步骤,直到得到树
信息增益的计算方式
- 熵, 假定当前样本集合D中第k类样本所占的比例为 p k ( k = 1 , 2 , . . . , ∣ y ∣ ) p_k(k = 1, 2, ..., |y|) pk(k=1,2,...,∣y∣)
E n t ( D ) = − ∑ k = 1 ∣ y ∣ p k l o g 2 p k Ent(D) = -\sum_{k=1}^{|y|}{p_klog_2p_k} Ent(D)=−k=1∑∣y∣pklog2pk
其中 x x x是特征 X X X的各个属性值
- 信息增益
G a i n ( D , a ) = E n t ( D ) − ∑ v ∈ v a l u e ( a ) n u m ( D v ) n u m ( D ) E n t ( D v ) Gain(D,a) = Ent(D) - \sum_{v \in value(a)}{\frac{num(D_v)}{num(D)}Ent(D_v)} Gain(D,a)=Ent(D)−v∈value(a)∑num(D)num(Dv)Ent(Dv)
举个例子,
- 样本集合 D D D有20个,12个是类别1,8个是类别0
- 特征
A
A
A有三个属性值
A
1
,
A
2
,
A
3
A_1,A_2,A_3
A1,A2,A3,
- A 1 A_1 A1🈶️6个样本,其中3个1,3个0
- A 2 A_2 A2有4个样本,其中3个1,1个0
- A 3 A_3 A3有10个样本,其中6个1,4个0
则
H ( D ) = − ( 12 20 l o g 2 12 20 + 8 20 l o g 2 8 20 ) H ( D ∣ A ) = 6 20 ∗ ( − ( 3 6 l o g 2 3 6 + 3 6 l o g 2 3 6 ) ) + 4 20 ∗ ( − ( 3 4 l o g 2 3 4 + 1 4 l o g 2 1 4 ) ) + 10 20 ∗ ( − ( 6 10 l o g 2 6 10 + 4 10 l o g 2 4 10 ) ) H(D) = -(\frac{12}{20}log_2{\frac{12}{20}} + \frac{8}{20}log_2{\frac{8}{20}})\\ H(D|A) = \frac{6}{20}*(-(\frac{3}{6}log_2{\frac{3}{6}} + \frac{3}{6}log_2{\frac{3}{6}})) + \frac{4}{20}*(-(\frac{3}{4}log_2{\frac{3}{4}} + \frac{1}{4}log_2{\frac{1}{4}})) + \frac{10}{20}*(-(\frac{6}{10}log_2{\frac{6}{10}} + \frac{4}{10}log_2{\frac{4}{10}})) H(D)=−(2012log22012+208log2208)H(D∣A)=206∗(−(63log263+63log263))+204∗(−(43log243+41log241))+2010∗(−(106log2106+104log2104))
优缺点
- ID3不能保证得到最优解决方案。它可以收敛于局部最优。它使用一种贪婪策略,在每次迭代中选择局部最佳属性来分割数据集。该算法在搜索最优决策树时采用回溯法,以可能花费更长的时间为代价,提高了算法的最优性。
- ID3可能对训练数据进行过拟合。为了避免过拟合,较小的决策树应该优于较大的决策树。这种算法通常产生小的树,但它可能并不总是产生最小的决策树。
- 在连续数据上使用ID3比在类型数据上更难(类型数据的可能值是离散的,因此减少了可能的分支点)。如果任何给定属性的值是连续的,那么就有更多的地方可以分割该属性上的数据,而搜索分割的最佳值可能非常耗时。
- 用信息增益作为标准容易偏向于取值较多的特征
- 缺失值没有进行处理
C4.5
C4.5对ID3的改进:
- 处理连续和离散特征 - 为了处理连续特征,C4.5创建一个阈值,然后将列表分为属性值高于阈值的列表和那些小于或等于它的列表
- C4.5的思路是将连续的特征离散化。比如n个样本的连续特征A的值有n个,从小到大排列为 𝑎 1 , 𝑎 2 , . . . , 𝑎 n 𝑎_1,𝑎_2,...,𝑎_n a1,a2,...,an,则C4.5取相邻两样本值的平均数,一共取得 n − 1 n-1 n−1个划分点,其中第 i i i个划分点 𝑇 𝑖 𝑇_𝑖 Ti表示为: 𝑇 𝑖 = 𝑎 𝑖 + 𝑎 𝑖 + 1 2 𝑇_𝑖=\frac{𝑎_𝑖+𝑎_{𝑖+1}}{2} Ti=2ai+ai+1。对于这 n − 1 n-1 n−1个点,分别计算以该点作为二元分类点时的信息增益。选择信息增益最大的点作为该连续特征的二元离散分类点
- 处理缺失值-C4.5允许将属性值缺失的标记为?。缺失属性值在增益和熵计算中根本不使用
- 样本某些特征缺失的情况下选择划分的属性
- 对于某一个有缺失特征值的特征A。C4.5的思路是将数据分成两部分,对每个样本设置一个权重(初始可以都为1),然后划分数据,一部分是有特征值A的数据 D 1 D_1 D1,另一部分是没有特征A的数据 D 0 D_0 D0. 然后对于没有缺失特征A的数据集 D 1 D_1 D1来和对应的A特征的各个特征值一起计算加权重后的信息增益比,最后乘上特征A缺失的样本占总样本的比例
- 选定了划分属性,对于在该属性上缺失特征的样本的处理
- 可以将缺失特征A的样本同时划分入所有的子节点,不过将这些样本的权重按各个子节点有特征A的样本的数量比例来分配
- 样本某些特征缺失的情况下选择划分的属性
- Handling attributes with differing costs.
- 创建后修剪树木-C4.5一旦创建树就回顾树,并试图用叶子节点代替那些无用的节点
- 用信息增益率代替信息增益:减轻信息增益作为标准容易偏向于取值较多的特征的问题
G a i n _ r a t i o ( D , a ) = G a i n ( D , a ) I V ( a ) I V ( a ) = − ∑ v ∈ v a l u e ( A ) n u m ( D v ) n u m ( D ) l o g 2 ( n u m ( D v ) n u m ( D ) ) Gain\_ratio(D, a) = \frac{Gain(D, a)}{IV(a)}\\ IV(a) = - \sum_{v \in value(A)}{\frac{num(D_v)}{num(D)}log_2(\frac{num(D_v)}{num(D)})} Gain_ratio(D,a)=IV(a)Gain(D,a)IV(a)=−v∈value(A)∑num(D)num(Dv)log2(num(D)num(Dv))
需注意的是,增益率准则对可取值数目较少的属性有所偏好。因此,C4.5算法并不是直接选择增益率最大的候选划分属性,而是使用了一个启发式,先从候选划分属性中找出信息增益高于平均水平的属性,再从 中选择增益率最高的.
优缺点
- C4.5生成的是多叉树,即一个父节点可以有多个节点。
- C4.5由于使用了熵模型,里面有大量的耗时的对数运算,如果是连续值还有大量的排序运算
- C4.5只能用于分类
CART
分类树
二叉树,前面的2个是多叉树
划分准则
gini系数:越小代表数据集D纯度越高
G i n i ( D ) = ∑ k = 1 ∣ y ∣ ∑ k ∗ ! = k p k p k ∗ = 1 − ∑ k = 1 ∣ y ∣ p k 2 G i n i _ i n d e x ( D , a ) = ∑ v ∈ v a l u e ( a ) n u m ( D v ) n u m ( D ) G i n i ( D v ) Gini(D) = \sum_{k=1}^{|y|}{\sum_{k^*!=k}{p_kp_{k^*}}} = 1 - \sum_{k=1}^{|y|}{p_k^2}\\ Gini\_index(D, a) = \sum_{v \in value(a)}{\frac{num(D_v)}{num(D)}Gini(D_v)} Gini(D)=k=1∑∣y∣k∗!=k∑pkpk∗=1−k=1∑∣y∣pk2Gini_index(D,a)=v∈value(a)∑num(D)num(Dv)Gini(Dv)
选择特征标准:
a ∗ = a r g m i n a ∈ A G i n i _ i n d e x ( D , a ) a_* = arg min_{a \in A} Gini\_index(D, a) a∗=argmina∈AGini_index(D,a)
对连续特征的处理
和C4.5一样,只是每次是进行二元划分,之后该特征也还是可以参与划分的,即没有 A − a ∗ A-{a_*} A−a∗
对离散特征的处理
假设离散特征 a ∗ a_* a∗有1,2,3,4,四种取值,则需要将其分为
- {1}, {2,3,4}
- {2}, {1,3,4}
- {3}, {1,2,4}
- {4}, {1,2,3}
- {1,2}, {3,4}
- {1,3}, {2,4}
- {1,4}, {2,3}
不断去计算划分时的gini系数来进行划分
与ID3, C4.5不同的是,之后该特征也还是可以参与划分的
回归树
回归树与分类树差不多,不同之处在于以下2点
- 特征划分采取的划分准则不同
- 树的输出不同
回归树的划分准则
以和方差最小作为划分准则,将特征A的特征值分为 A − , A + A^{-}, A^{+} A−,A+
a r g m i n ∑ i ∈ A − ( y i − c − ) 2 + ∑ i ∈ A + ( y i − c + ) 2 argmin \sum_{i\in A^{-}}{(y_i-c^{-})^2} + \sum_{i\in A^{+}}{(y_i-c^{+})^2} argmini∈A−∑(yi−c−)2+i∈A+∑(yi−c+)2
回归树的输出
输出为叶子节点的均值或者中位数,而分类树输出的是最多的那个类别
优缺点
- ID3, C4.5, CART,都是选择最优的一个特征来做划分,但实际上大多数的划分不应该是由某一个单一特征决定的,而可能是由一组特征决定。这种决策树叫做多变量决策树(代表-OC1)
- 加入一点扰动,结构就可能变化
Tips on practical use
- 决策树倾向于在具有大量特征的数据上过度拟合。获取正确的样本与特征数量的比率很重要,因为在高维空间中,但只有很少样本的树很可能会过拟合。
- 考虑执行降维方法(PCA, ICA,或特征选择),以使树有更好的机会找到具有区别性的特征
- 理解决策树结构将有助于获得关于决策树如何进行预测的更多见解,这对于理解数据中的重要特征非常重要
- 通过使用
export
函数在训练时可视化树。使用max depth=3
作为初始树深度,以获得树如何适合数据的感觉,然后增加深度 - 请记住,填充树所需的样本数量会随着树的增长而增加一倍。使用最大深度控制树的大小,以防止过拟合
- 使用
min - samples split
或min - samples leaf
来确保多个样本支持树中的每个决策,通过控制来考虑哪些分裂。一个非常小的数字通常意味着树将过度拟合,而一个大的数字将阻止树学习数据。尝试min - samples leaf=5
作为初始值。如果样本量变化很大,可以在这两个参数中使用一个浮点数作为百分比。min samples split
可以创建任意小的叶子,min samples leaf
保证每个叶子都有一个最小的大小,避免低方差、过拟合的叶子节点i - 在训练之前平衡你的数据集,以防止树向占优势的类倾斜。类别平衡可以通过从每个类别中抽样相等数量的样本来实现,或者最好通过将每个类别的样本权重(样本权重)的总和规范化到相同的值来实现。还需要注意的是,基于权重的预修剪标准,如
min_weight_fraction_leaf
,将比不知道样本权重的标准,如min_samples_leaf
,更少地偏向于优势类 - If the samples are weighted, it will be easier to optimize the tree structure using weight-based pre-pruning criterion such as min_weight_fraction_leaf, which ensure that leaf nodes contain at least a fraction of the overall sum of the sample weights.
参考
实践部分
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
from sklearn.tree import DecisionTreeClassifier
iris = load_iris()
clf = DecisionTreeClassifier(
random_state=0,
criterion='gini', # criterion{“gini”, “entropy”, “log_loss”}, default=”gini”
splitter='best', # {“best”, “random”}, default=”best”
max_depth=None, # int, default=None, 一般从3开始
min_samples_split=2, # int or float, default=2,The minimum number of samples required to split an internal node:
min_samples_leaf=1, # int or float, default=1, 一般从5开始,The minimum number of samples required to be at a leaf node.
min_weight_fraction_leaf=0.0, # The minimum weighted fraction of the sum total of weights (of all the input samples) required to be at a leaf node
max_features=None, # int, float or {“auto”, “sqrt”, “log2”}, default=None The number of features to consider when looking for the best split:
max_leaf_nodes=None,
min_impurity_decrease=0.0,
class_weight=None, # dict, list of dict or “balanced”, default=None
ccp_alpha=0.0
)
cross_val_score(clf, iris.data, iris.target, cv=10)
array([1. , 0.93333333, 1. , 0.93333333, 0.93333333,
0.86666667, 0.93333333, 1. , 1. , 1. ])
常见问题
- 决策树的优缺点?
- 优点
- 原理简单,易解释
- 基本不需要预处理:不需要归一化,处理缺失值等。
- 贴合计算机性能,使用决策树预测的代价是 O ( l o g 2 n ) O(log_2n) O(log2n)。n为样本数。
- 既可以处理离散值也可以处理连续值。
- 可以处理多维度输出的分类问题。
- 对于异常点的容错能力好,健壮性高。
- 缺点
- 决策树算法非常容易过拟合。
- 决策树会因为样本发生一点点的改动,就会导致树结构的剧烈改变
- 寻找最优的决策树是一个
NP
难的问题,我们一般是通过启发式方法,容易陷入局部最优 - 有些比较复杂的关系,决策树很难学习,比如异或
- 如果某些特征的样本比例过大,生成决策树容易偏向于这些特征
- 优点
- ID3, C4.5, CART的联系与区别
- ID3,分类,多叉树,信息增益,不支持连续特征处理,不支持缺失值处理,不支持剪枝
- C4.5,分类,多叉树,信息增益率,支持连续特征处理,支持缺失值处理,支持剪枝
- CART,分类、回归,二叉树,gini,,支持连续特征处理,支持缺失值处理,支持剪枝