决策树是一种分类模型,如下图:
根据这棵树,我们就可以一步步进行判断。构建决策树的目标是希望每个分支节点包含的样本尽量属于同一个类别,为了衡量这种节点的纯度,引入了信息熵的概念,假设当前样本集合D中第k类样本所占的比例为pk,则D的信息熵定义为
E n t ( D ) = − ∑ k = 1 ∣ y ∣ p k l o g 2 p k Ent(D) = -\sum_{k=1}^{|y|} p_k log_2 p_k Ent(D)=−k=1∑∣y∣pklog2pk
上面的公式,可以简单算一下,假设现在一个节点有10个样本,一种情况是10个样本都来自不同类别,一种情况是10个样本都属于同一类别,对比一下就知道后者的信息熵低很多,因此信息熵的值越小,节点的纯度越高。
信息熵衡量的是节点的纯度,而我们希望构建一颗决策树,其实就是分析出每个节点具体通过什么属性进行分类,比如说上图根节点选择了纹理,子节点选择了根蒂和触感,在分析父节点选择什么属性的时候,单纯的信息熵是没有办法帮助我们选择的,所以还需要引入信息增益的概念,所谓信息增益,就是衡量选择属性a进行分类的话,对于纯度的提升有多大帮助,纯度的提升通过分类前和分类后的纯度进行对比,也就是通过父节点和子节点进行对比,
G a i n ( D , a ) = E n t ( D ) − ∑ v = 1 V D v D E n t ( D v ) Gain(D,a) = Ent(D) - \sum_{v=1}^V \frac{D^v}{D}Ent(D^v) Gain(D,a)=Ent(D)−v=1∑VDDvEnt(Dv)
其中Dv表示分类后的每个子节点的样本量,以上图的为例,如果父节点选择纹理作为分类的属性,那么就会产生清晰、稍糊和模糊三个节点,信息增益就是计算父节点的信息熵和各个子节点的信息熵的加权求和的差值,权重是子节点数量占总数量的比值。
理解了信息增益的概念,其实我们就可以通过计算各种属性的信息增益,然后挑选信息增益最大的属性,上图最终通过计算确定了纹理作为父节点,纹理有三个子节点,注意到模糊这个子节点只包含坏瓜的样本,所以不需要计算分析这个节点的分类属性,而对于清晰和稍糊这两个节点,则继续重复刚刚的流程,通过计算信息增益确定分类属性,直到最后每个节点都达到信息熵的阈值,即可完成一棵决策树的构建,整个构建流程成为ID3。
除了上述的构建流程,还有一种改进版本的流程称为C4.5,ID3的流程有什么缺陷呢,我们可以考虑一下,在计算信息增益的时候,如果有一个属性,它的分类节点很多,比如我们根据每个瓜的编号进行划分,那么不同的瓜就会划分到不同的子节点,每个子节点只有一个样本,这时候信息增益当然很大,而且马上就满足每个子节点的信息熵达到最小,可是这样的分类毫无意义,所以在具体分析的时候,也会考虑到分类属性划分的子类太多也不好,因此C4.5就定义了增益率,在信息增益中引入一个关于分类子类数量的惩罚项,
G a i n _ r a t i o ( D , a ) = G a i n ( D , a ) I V ( a ) Gain\_ratio(D,a) = \frac{Gain(D,a)}{IV(a)} Gain_ratio(D,a)=IV(a)Gain(D,a)
I V ( a ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ l o g 2 ∣ D v ∣ ∣ D ∣ IV(a) = \sum_{v=1}^V \frac{|D^v|}{|D|} log_2 \frac{|D^v|}{|D|} IV(a)=v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
类别a的子类数量越多,IV(a)就会越大,增益率就会相对减少。总的来说,C4.5就是利用信息增益率作为节点分类属性选择的标准,这是和ID3的主要区别。
前面介绍的ID3和C4.5一般都是用于分类树,接下来我们看看怎么利用树去解决回归问题。
分类与回归树CART(classification and regression tree)既可以用于分类也可以用于回归,用途更广,所以boosting中的GBDT其实用的也是CART而不是ID3或者C4.5。
首先我们来看看如何生成一棵回归树,一棵回归树其实就是把输入空间划分为一个个子空间,每个子空间对应着相应的输出
f ( x ) = ∑ m = 1 M c m I ( x ∈ R m ) f(x) = \sum _{m=1} ^M c_m I(x \in R_m) f(x)=m=1∑McmI(x∈Rm)
其中cm就是子空间m对应的输出,假如输入x属于子空间m,则最终输出cm。所以我觉得其实一棵回归树就像是一个分段函数。
接下来,主要问题就是如何对输入空间进行划分,也就是确定划分变量和划分点,以上图为例,就是如何确定根节点选择start,如何确定划分的点是8.5。
假设我们选择第j个输入变量和它取的值s作为划分变量和划分点,定义划分后的两个区域为
R
1
(
j
,
s
)
=
{
x
∣
x
(
j
)
≤
s
}
R_1 (j, s)=\{x|x^{(j)} \leq s\}
R1(j,s)={x∣x(j)≤s}
R
2
(
j
,
s
)
=
{
x
∣
x
(
j
)
≥
s
}
R_2 (j, s)=\{x|x^{(j)} \geq s\}
R2(j,s)={x∣x(j)≥s}
寻找当前节点的最优划分变量和最优切分点,即
m i n j , s [ m i n c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2 ] min_{j,s}[min_{c_1}\sum_{x_i \in R_1(j,s)} (y_i - c1)^2 + min_{c_2}\sum_{x_i \in R_2(j,s)} (y_i - c2)^2 ] minj,s[minc1xi∈R1(j,s)∑(yi−c1)2+minc2xi∈R2(j,s)∑(yi−c2)2]
对于上式中的c1和c2其实很容易求,
c
^
1
=
a
v
e
(
y
i
∣
x
i
∈
R
1
(
j
,
s
)
)
\hat c_1 = ave(y_i | x_i \in R_1(j,s))
c^1=ave(yi∣xi∈R1(j,s))
c
^
2
=
a
v
e
(
y
i
∣
x
i
∈
R
2
(
j
,
s
)
)
\hat c_2 = ave(y_i | x_i \in R_2(j,s))
c^2=ave(yi∣xi∈R2(j,s))
所以对于某一具体的划分变量j,我们就可以通过最优化上式,求出最优的划分变量s,同时也计算出对应的损失
L o s s j = ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2 Loss_j =\sum_{x_i \in R_1(j,s)} (y_i - c1)^2 + \sum_{x_i \in R_2(j,s)} (y_i - c2)^2 Lossj=xi∈R1(j,s)∑(yi−c1)2+xi∈R2(j,s)∑(yi−c2)2
这样,我们就可以遍历所有的划分变量,对比各自的损失,选出最小损失的变量作为划分变量,这样,就可以确定出当前节点选择哪个划分变量以及相应的划分点了。
上面我们讨论了如何构建一棵回归树,接下来继续看看如何构建一棵分类树。
分类树选择通过基尼指数进行特征选择,同时决定最优切分点。
对于给定的样本集合D,基尼指数为
G i n i ( D ) = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 Gini(D) = 1- \sum_{k=1} ^K (\frac{|C_k|}{|D|})^2 Gini(D)=1−k=1∑K(∣D∣∣Ck∣)2
其中,Ck是D中属于第k类的样本子集,K是类别的个数。
假设有一个集合有10个元素,每个元素都属于同一个类别,那么基尼指数就是0,如果每个元素都属于不同的类别,一共有10个类别,那么基尼指数就是0.9,所以基尼指数越小,集合的纯度就越高。
如果样本集合D根据特征A是否可取某一可能值a被分割为D1和D2两部分,即
D
1
=
{
(
x
,
y
)
∈
D
∣
A
(
x
)
=
a
}
D_1 = \{(x, y) \in D | A(x) =a\}
D1={(x,y)∈D∣A(x)=a}
D
2
=
D
−
D
1
D_2 = D - D_1
D2=D−D1
然后,我们就可以进一步定义在特征A下集合D的基尼指数
G i n i ( D , A ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini(D,A) = \frac{|D_1|}{|D|} Gini(D_1) + \frac{|D_2|}{|D|} Gini(D_2) Gini(D,A)=∣D∣∣D1∣Gini(D1)+∣D∣∣D2∣Gini(D2)
这样,我们就可以遍历特征A不同的可能取值,分别计算出相对应的基尼指数,从而确定出特征A的最优划分点。
最后,我们当然还要分别计算不同特征的基尼指数,从而确定出当前节点的最优特征。
这里有个地方需要注意,我们划分两个子空间,是通过特征值是否等于某个值,而不是特征值大于或者小于某个值进行划分。这是《统计学习方法》这本书的说法,我个人觉得这个还是看实际情况,如果说这个特征只能取某几个特定值,比如用0和1表示有工作和没工作,那么上述的流程没问题,如果像回归树那样取值是一个连续变量,那么我们还是需要计算出最优划分点。
本文主要简单介绍了一下ID3、C4.5和CART,在构建一棵树之后,我们还需要进行剪枝处理、缺失值处理等等,有兴趣的朋友可以进一步深入了解。