前一篇文章说了决策树算法的一些基本内容,包括它的分类和如何构造决策树。这篇文章我们继续深入如何构造决策树
如何构造决策树
建树需要解决以下三个问题:
- 选择什么特征分裂
- 如何选择特征分裂的属性值(具体判断条件)
- 什么时候停止分裂
以下是损失函数关键的公式
熵:
e
n
t
r
o
p
y
(
D
)
=
−
∑
i
=
1
n
P
i
l
o
g
2
P
i
entropy(D) = -\sum_{i=1}^n P_ilog_2 P_i
entropy(D)=−i=1∑nPilog2Pi
条件熵(加特征分裂后的情况):
e
n
t
r
o
p
y
(
D
,
A
)
=
∑
i
=
1
k
D
A
i
D
l
o
g
2
D
A
i
entropy(D,A) = \sum_{i=1}^k \frac {D_{A_i}}{D} log_2D_{A_i}
entropy(D,A)=i=1∑kDDAilog2DAi
信息增益:
g
a
i
n
(
D
,
A
)
=
e
n
t
r
o
p
y
(
D
)
−
e
n
t
r
o
p
y
(
D
,
A
)
gain(D,A) = entropy(D) - entropy(D,A)
gain(D,A)=entropy(D)−entropy(D,A)
信息增益率:
g
a
i
n
r
(
D
,
A
)
=
g
a
i
n
(
D
,
A
)
/
e
n
t
r
o
p
y
(
D
,
A
)
gain_r(D,A) = gain(D,A)/entropy(D,A)
gainr(D,A)=gain(D,A)/entropy(D,A)
上篇文章也提到了,根据构造算法的不同,决策树可分为三种:ID3, C4.5, CART
ID3
这种构建树的算法是通过信息增益(不是信息增益率喔!)来进行特征选择的,而信息增益是由两个熵相减得来的,是由经过特征分裂后的熵减去分裂前结点的熵。
熵是什么呢,熵是一种不确定性,一开始你数据的熵肯定是最大的,你建树的目的就是想要把你数据的不确定性一步一步地减少,使一个结点中的数据更纯(也就是我们说的分好了类)。
当前一个熵给定的时候,我们要做的就是使分裂后的熵(entropy(D,A))尽可能地小。
这样问题就来了,ID3会去选择子类别多的特征,因为这样分裂出来的结果会更纯,熵会更小,这有偏于我们的初衷,我们要的纯不是想通过让它分类分的更细得来的纯啊!如果这样那不如分100个类好了里面数据的纯度都很高。
还有就是它无法对连续型变量和缺省值进行处理。
总结一下就是
- ID3选用信息增益进行特征选择
- 第一个缺点是,由于信息增益的计算公式,ID3会偏向选择子类别多的特征
- 第二个缺点是,ID3无法处理连续型变量
C4.5
ID3有这两个缺点就决定了他选择的主观性偏强,并且也存在较大的局限性。于是C4.5就出来解决ID3的缺点。
首先为了解决第一个缺点,即偏向选择子类别多的特征,C4.5采用了信息增益率进行特征选择,弱化了主观性地偏向子类别多的特征选择。
为了解决第二个缺点,C4.5用以下算法处理连续值(和离散化连续值很像)
把连续值变量进行排序成(a1,a2,…an)
再从(a1,a2)区间里取A1作为分界来分裂数据,算信息增益率,从(a2,a3)区间里取A2作为分界来分裂数据,算信息增益率,这样可以得到n-1个信息增益率,然后选最大的。
总结一下:
- C4.5是ID3的改进,采用信息增益率进行特征选择。
- 为了处理连续值,C4.5采用单点离散化的思想,用信息增益率来进行连续值特征的属性值选择。
- 第一个缺点是C4.5时间耗费大,看连续值处理那块可以看出
- 第二个缺点是C4.5没解决回归问题
CART
以上两种算法都是解决分类问题的,那么回归问题呢?
我们使用CART(分类回归树)来解决回归问题,CART是一颗二叉树,哪怕某个特征有多类(年龄有青年,中年,老年),也是进行二分叉(青年一个叉,中年老年一个叉)再继续分下去。
而之后树相关的集成算法如随机森林,GDBT,XGBoost中的弱分类器用的都是CART。
关于分类问题,CART和ID3, C4.5的思想是一样的,用损失函数来划分特征,选择特征划分的属性值。只是ID3,C4.5用的是信息增益,CART用的是基尼指数。
基尼指数:
g
i
n
i
(
D
)
=
∑
i
=
1
n
p
k
(
1
−
p
k
)
gini(D) = \sum_{i=1}^n p_k (1-p_k)
gini(D)=i=1∑npk(1−pk)因为基尼指数也可以表示不确定性,和熵类似,基尼指数也有条件基尼指数:
g
i
n
i
(
D
,
A
)
=
∑
i
=
1
k
D
A
i
D
g
i
n
i
(
D
A
i
)
gini(D,A) = \sum_{i=1}^k \frac {D_{A_i}}{D} gini(D_{A_i})
gini(D,A)=i=1∑kDDAigini(DAi)
关于回归问题,对于一个数据集我们可以将其分为n个子区间
(
A
1
,
A
2
.
.
.
.
.
.
A
n
)
(A_1,A_2......A_n)
(A1,A2......An)。对于任一区间
A
j
A_j
Aj,我们可以产生一个对应的输出
C
j
C_j
Cj,其可以表示为
C
j
=
a
v
g
(
y
i
∣
x
i
)
(
x
i
∈
A
j
)
C_j = avg(y_i|x_i)(x_i \in A_j)
Cj=avg(yi∣xi)(xi∈Aj)它就是区间
A
j
A_j
Aj 上所有
x
i
x_i
xi 对应的
y
i
y_i
yi的均值
而对于1个数据:x 而言,它会落在我们的某个区间,所以根据我们的划分,会给它分配那个它落到区间的
C
i
C_i
Ci值,看上去是个求和,但是因为x只能落在一个区间内,所以指标函数只在Ai是x分到的区间时取1。
f
(
x
)
=
∑
i
=
1
n
C
i
I
(
x
∈
A
i
)
f(x)=\sum_{i=1}^nC_iI(x \in A_i)
f(x)=i=1∑nCiI(x∈Ai)对于一个给定的回归树我们用平方误差来表示每个单元的损失:
L
=
∑
x
i
∈
A
j
(
y
i
−
f
(
x
i
)
)
2
L = \sum_{x_i \in A_j}(y_i-f(x_i))^2
L=xi∈Aj∑(yi−f(xi))2那么我们每个单元的最优输出就是使L最小。
我们需要解决的问题是如何确定特征划分时的属性值,和C4.5一样,对于连续型特征采用单点离散化处理,把所有切分点都试一遍,分成两份进行损失函数的计算,确定一个最好的切分点。
总结
- ID3选用信息增益作为损失函数,具有对多类特征的选择偏向性,且不能处理连续型特征。
- C4.5在ID3的基础上进行了改进,如选择信息增益率作为损失函数,采用单点离散化对连续型特征进行处理,但是不能处理回归问题。
- CART对于分类问题选用基尼指数作为损失函数,对于回归问题使用平方误差作为损失函数,一个结点里的预测值采用的是这个结点里数据结果的平均数(比如房价)。
- 这三类算法都是贪心算法,找到的是局部最优分裂方法。