常用决策树模型介绍与python实现

1. 引言

    决策树(decision tree)是一种基本的分类和回归方法,由于其采用的是一种树形的结构,因此,具有很强的解释性和计算速度,也正是因为这些特点,使得决策树在很多行业都得到了应用,比如风控行业等。决策树的建模过程一般分为三个步骤:特征选择、决策树的生成和决策树的剪枝,根据这三个步骤所采用的规则,衍生出了很多不同的模型,比较经典的有Quinlan在1986年提出的ID3算法和1993年提出的C4.5算法,以及Breiman等人在1984年提出的CART算法,本文将以分类决策树为例,对这几个算法分别进行介绍,并用python进行实现。

2. 常用决策树模型介绍

2.1 决策树的定义

    决策树是由结点和有向边组成的树形结构,其中,结点包含两种类型:内部结点和叶结点。内部结点表示一个特征或者属性,叶结点则表示一个类。如下图所示,其中每个圆圈表示内部结点,每个正方形表示叶结点。
常用决策树模型介绍与python实现_第1张图片
    对于给定的训练数据集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x N , y N ) } D=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\} D={(x1,y1),(x2,y2),,(xN,yN)},其中, x i = ( x i ( 1 ) , x i ( 2 ) , ⋯   , x i ( n ) ) T x_{i}=\left(x_{i}^{(1)}, x_{i}^{(2)}, \cdots, x_{i}^{(n)}\right)^{\mathrm{T}} xi=(xi(1),xi(2),,xi(n))T表示输入的特征向量, n n n为特征的个数, y i ∈ { 1 , 2 , ⋯   , K } y_{i} \in\{1,2, \cdots, K\} yi{1,2,,K}为类别标记, K K K表示类别的个数, N N N表示训练集的大小。决策树的思想大致如下:

  1. 首先,构建根结点,然后将整个训练集都放在根结点。
  2. 接着,从所有特征中选择一个最优特征,并根据该特征将训练数据集分割为多个子集,使得每一个子集有一个当前条件下的最好分类,如果某个子集已经基本分类正确,则将其作为叶结点,其对应的类别作为该叶结点的类别,否则,对每个子集继续选择最优的特征进行分割,如此递归下去,直到所有的子集基本被正确分类为止。最后,每个叶结点都代表一个子集,也是特征空间中的一个子区域,每个子区域之间都是不相交的。
  3. 最后,由于第二步为了将训练集划分正确,往往构建的决策树会过于庞大,这时,模型可能会出现过拟合,导致对新的测试数据可能分类效果不好,因此,需要对决策树自下而上进行剪枝,去掉一些过于细分的叶结点,使其回退到父结点或者更高的结点,然后将父结点或者更高的结点作为新的叶结点。

    这样一来,当对一个实例 x x x进行预测时,会根据决策树的分支情况,将实例 x x x划分到其归属的叶结点,并将该叶结点对应的类别作为实例 x x x的预测类别,从而达到分类的效果。下面,我们将根据决策树的三个步骤,对各个算法的思想进行介绍和对比。

2.2 ID3算法

适用场景:特征和目标变量都是离散型

2.2.1 特征选择——信息增益

    特征选择是指决策树在每一次分支时,从所有的特征中选择能够对当前数据集具有最优分类能力的特征,这样可以提高模型的学习效率。ID3决策树的特征选择采用的是信息增益的方法。在介绍信息增益的概念之前,需要先介绍一下条件熵的概念。

    在信息论中,熵表示随机变量不确定性的度量,设 X X X是一个取有限个值的离散随机变量,则其熵的计算公式如下:
H ( X ) = − ∑ i = 1 n p i log ⁡ p i H(X)=-\sum_{i=1}^{n} p_{i} \log p_{i} H(X)=i=1npilogpi其中, p i = P ( X = x i ) , i = 1 , 2 , ⋯   , n p_{i}=P\left(X=x_{i}\right), \quad i=1,2, \cdots, n pi=P(X=xi),i=1,2,,n表示 X X X取某个类别时的概率,当 p i = 0 p_{i}=0 pi=0时,定义 0 log ⁡ 0 = 0 0 \log 0=0 0log0=0,由于熵只依赖于 X X X的分布,因此,也可以将 X X X的熵记作 H ( p ) H(p) H(p),即
H ( p ) = − ∑ i = 1 n p i log ⁡ p i H(p)=-\sum_{i=1}^{n} p_{i} \log p_{i} H(p)=i=1npilogpi从熵的计算公式可以发现,当随机变量的不确定性越大时,熵的值会越大,其取值范围为:
0 ⩽ H ( p ) ⩽ log ⁡ n 0 \leqslant H(p) \leqslant \log n 0H(p)logn

    条件熵则表示在已知随机变量 X X X的条件下随机变量 Y Y Y的不确定性,其计算公式如下:
H ( Y ∣ X ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) H(Y | X)=\sum_{i=1}^{n} p_{i} H\left(Y | X=x_{i}\right) H(YX)=i=1npiH(YX=xi)其中, p i = P ( X = x i ) , i = 1 , 2 , ⋯   , n p_{i}=P\left(X=x_{i}\right), \quad i=1,2, \cdots, n pi=P(X=xi),i=1,2,,n

    信息增益则表示在得知特征 X X X的信息而使得类 Y Y Y的信息的不确定性减少的程度。其计算公式如下:
g ( Y , X ) = H ( Y ) − H ( Y ∣ X ) g(Y, X)=H(Y)-H(Y | X) g(Y,X)=H(Y)H(YX)当信息增益越大时,表示给定 X X X后,对 Y Y Y进行分类后的不确定性越低,也就是说 X X X Y Y Y的分类能力越强。因此,ID3在每一次分支时,采用信息增益作为每个结点特征选择的规则。

2.2.2 ID3决策树的构造

    ID3算法构造决策树的思想大致如下:首先从根结点开始,对结点,对结点计算所有可能特征的信息增益,选择信息增益最大的特征作为结点的特征,由该特征的不同取值建立子结点,再对子结点递归地调用以上方法,构建决策树,直到所有特征的信息增益均很小或没有特征可以选择为止,最终得到一个决策树。其具体的算法步骤如下:

  1. 给定训练数据集 D D D,特征集 A A A,阈值 ε \varepsilon ε;
  2. D D D中所有实例属于同一类 C k C_k Ck,则T为单结点树,并将类 C k C_k Ck作为该结点的类标记,返回决策树 T T T;
  3. A = ∅ A=\varnothing A=,则 T T T为单结点树,并将 D D D中实例数最大的类 C k C_k Ck作为该结点的类标记,返回决策树 T T T
  4. 否则,计算 A A A中各特征对 D D D的信息增益,选择信息增益最大的特征 A g A_g Ag
  5. 如果 A g A_g Ag的信息增益小于阈值 ε \varepsilon ε,则 T T T为单结点树,并将 D D D中实例数最大的类 C k C_k Ck作为该结点的类标记,返回决策树 T T T;
  6. 否则,对 A g A_g Ag的每一可能值 a i a_i ai,依 A g = a i A_{g}=a_{i} Ag=ai D D D分割为若干非空子集 D i D_i Di,将 D i D_i Di中实例数最大的类作为标记,构建子结点,由结点及其子结点构成树 T T T,返回 T T T
  7. 对第 i i i个子结点,以 D i D_i Di为训练集,以 A − A g A-{A_g} AAg为特征集,递归地调用2~6步,得到子树 T i T_i Ti,返回 T i T_i Ti

以上就是ID3决策树的构造过程,但是该过程构建的决策树往往会出现过拟合,因此,需要对树进行剪枝。

2.2.3 ID3决策树的剪枝

    决策树的剪枝是指从已生成的树上裁剪掉一些子树或子结点,并将其根结点或者父结点作为新的叶结点,从而简化决策树模型。决策树的剪枝往往通过极小化决策树整体的的损失函数或代价函数来实现。设树 T T T ∣ T ∣ |T| T t t t是树 T T T的某个叶结点,该叶结点有 N t N_t Nt个样本点,其中 k k k类的样本点有 N t k N_{tk} Ntk个, k = 1 , 2 , ⋯   , K k=1,2, \cdots, K k=1,2,,K H t ( T ) H_{t}(T) Ht(T)为叶结点 t t t上的经验熵,\alpha \geqslant 0为惩罚参数,则决策树的损失函数可以定义为:
C α ( T ) = ∑ t = 1 ∣ T ∣ N t H t ( T ) + α ∣ T ∣ C_{\alpha}(T)=\sum_{t=1}^{|T|} N_{t} H_{t}(T)+\alpha|T| Cα(T)=t=1TNtHt(T)+αT其中,经验熵为:
H t ( T ) = − ∑ k N t k N t log ⁡ N t k N t H_{t}(T)=-\sum_{k} \frac{N_{t k}}{N_{t}} \log \frac{N_{t k}}{N_{t}} Ht(T)=kNtNtklogNtNtk将损失函数中的第一项记作:
C ( T ) = ∑ i = 1 ∣ T ∣ N t H t ( T ) = − ∑ t = 1 ∣ T ∣ ∑ k = 1 K N t k log ⁡ N t k N t C(T)=\sum_{i=1}^{|T|} N_{t} H_{t}(T)=-\sum_{t=1}^{|T|} \sum_{k=1}^{K} N_{t k} \log \frac{N_{t k}}{N_{t}} C(T)=i=1TNtHt(T)=t=1Tk=1KNtklogNtNtk则损失函数可以表达为:
C α ( T ) = C ( T ) + α ∣ T ∣ C_{\alpha}(T)=C(T)+\alpha|T| Cα(T)=C(T)+αT其中, C ( T ) C(T) C(T)表示模型对训练数据的预测误差,即模型对训练数据的拟合程度, ∣ T ∣ |T| T表示模型的复杂度,参数 α \alpha α则表示惩罚参数,当 α \alpha α越大时,则会选择越简单的树,反之,则选择较复杂的树。可以看出,决策树的剪枝不仅考虑模型的拟合程度,还考虑模型的复杂度,因此,相比决策树的构造过程,决策树的剪枝过程是一个全局优化的过程。决策树的剪枝步骤具体如下:

  1. 给定ID3算法生成的决策树 T T T,参数 α \alpha α;
  2. 递归地从树的叶结点向上回缩,设一组叶结点回缩到其父结点之前与之后的整体树分别为 T B T_B TB T A T_A TA,其对应的损失函数值分别为 C α ( T B ) C_{\alpha}\left(T_{B}\right) Cα(TB) C α ( T A ) C_{\alpha}\left(T_{A}\right) Cα(TA),如果 C α ( T A ) ⩽ C α ( T B ) C_{\alpha}\left(T_{A}\right) \leqslant C_{\alpha}\left(T_{B}\right) Cα(TA)Cα(TB),则进行剪枝,将其父结点变为新的叶结点。
  3. 重复步骤2,直到不能继续为止,此时得到损失函数最小的子树 T α T_{\alpha} Tα

以上就是关于ID3算法的整个过程,下面介绍一个与ID3算法非常接近的决策树算法,即C4.5。

2.3 C4.5算法

适用场景:特征和目标变量都是离散型

2.3.1 特征选择——信息增益比

    ID3选择的信息增益是一个绝对值的概念,对于不同的数据集,信息增益值往往不一样,对于分类问题困难时,其经验熵比较大,对应的信息增益值也会比较大,反之则比较小,因此,为了克服这个问题,C4.5对ID3算法的特征选择准则进行了改进。C4.5选取的特征选择准则是信息增益比,其定义就是将信息增益 g ( D , A ) g(D, A) g(D,A)与训练数据集 D D D的经验熵 H ( D ) H(D) H(D)之比,其计算公式如下:
g R ( D , A ) = g ( D , A ) H ( D ) g_{R}(D, A)=\frac{g(D, A)}{H(D)} gR(D,A)=H(D)g(D,A)

2.3.2 C4.5决策树的构造

     C4.5算法构造决策树的过程与ID3类似,只是将特征选择准则改为信息增益比,其他的都是一样的。

  1. 给定训练数据集 D D D,特征集 A A A,阈值 ε \varepsilon ε;
  2. D D D中所有实例属于同一类 C k C_k Ck,则T为单结点树,并将类 C k C_k Ck作为该结点的类标记,返回决策树 T T T;
  3. A = ∅ A=\varnothing A=,则 T T T为单结点树,并将 D D D中实例数最大的类 C k C_k Ck作为该结点的类标记,返回决策树 T T T
  4. 否则,计算 A A A中各特征对 D D D的信息增益比,选择信息增益比最大的特征 A g A_g Ag
  5. 如果 A g A_g Ag的信息增益比小于阈值 ε \varepsilon ε,则 T T T为单结点树,并将 D D D中实例数最大的类 C k C_k Ck作为该结点的类标记,返回决策树 T T T;
  6. 否则,对 A g A_g Ag的每一可能值 a i a_i ai,依 A g = a i A_{g}=a_{i} Ag=ai D D D分割为若干非空子集 D i D_i Di,将 D i D_i Di中实例数最大的类作为标记,构建子结点,由结点及其子结点构成树 T T T,返回 T T T
  7. 对第 i i i个子结点,以 D i D_i Di为训练集,以 A − A g A-{A_g} AAg为特征集,递归地调用2~6步,得到子树 T i T_i Ti,返回 T i T_i Ti
2.3.3 C4.5决策树的剪枝

    C4.5决策树的剪枝与ID3算法的一样,这里不再具体赘述。

2.4 CART算法

适用场景:支持数值型和离散型变量,支持分类和回归问题

2.4.1 特征选择——MSE或基尼指数

    CART算法与ID3和C4.5不同,CART构造的是一棵二叉树,即在每次分支时,会将每个特征划分为两个区域,左分支是取值为“是”的分支,右分支是取值为“否”的分支。对于回归树,CART一般采用平方误差最小化作为特征选择的准则,对于分类树,CART一般采用基尼指数作为特征选择的准则,假设有 K K K个类,样本点属于第 k k k类的概率为 p k p_{k} pk,则概率分布的基尼指数的定义为:
Gini ⁡ ( p ) = ∑ k = 1 K p k ( 1 − p k ) = 1 − ∑ k = 1 K p k 2 \operatorname{Gini}(p)=\sum_{k=1}^{K} p_{k}\left(1-p_{k}\right)=1-\sum_{k=1}^{K} p_{k}^{2} Gini(p)=k=1Kpk(1pk)=1k=1Kpk2如果样本集合 D D D根据特征 A A A是否取某一可能值 a a a被分割成 D 1 D_1 D1 D 2 D_2 D2两部分,即:
D 1 = { ( x , y ) ∈ D ∣ A ( x ) = a } , D 2 = D − D 1 D_{1}=\{(x, y) \in D | A(x)=a\}, \quad D_{2}=D-D_{1} D1={(x,y)DA(x)=a},D2=DD1则在特征 A A A的条件下,集合 D D D的基尼指数定义为:
Gini ⁡ ( D , A ) = ∣ D 1 ∣ ∣ D ∣ Gini ⁡ ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ Gini ⁡ ( D 2 ) \operatorname{Gini}(D, A)=\frac{\left|D_{1}\right|}{|D|} \operatorname{Gini}\left(D_{1}\right)+\frac{\left|D_{2}\right|}{|D|} \operatorname{Gini}\left(D_{2}\right) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)当基尼指数越大时,表示数据的不确定性越大,因此,CART分类树每次分支时,选择当前基尼指数 Gini ⁡ ( D , A ) \operatorname{Gini}(D, A) Gini(D,A)最小的特征作为当前结点的特征选择。

2.4.2 CART决策树的构造

    (一) 回归树的构造

    对于回归树的构造,假设 X X X Y Y Y分别为输入和输出变量,并且 Y Y Y是连续变量,给定训练数据集:
D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x N , y N ) } D=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\} D={(x1,y1),(x2,y2),,(xN,yN)}则回归树在每次分支时,会依次从特征集中选择第 j j j个变量 x ( j ) x^{(j)} x(j)和它取的值 s s s,作为切分变量和切分点,并定义两个区域:
R 1 ( j , s ) = { x ∣ x ( j ) ⩽ s } R 2 ( j , s ) = { x ∣ x ( j ) > s } R_{1}(j, s)=\left\{x | x^{(j)} \leqslant s\right\} \\ R_{2}(j, s)=\left\{x | x^{(j)}>s\right\} R1(j,s)={xx(j)s}R2(j,s)={xx(j)>s}然后计算两个区域中 Y Y Y的均值分别作为两个区域的预测值 c 1 c_1 c1 c 2 c_2 c2,接着,计算两个区域的平方误差和,并从中选择可以平方误差和最小的变量和切分点作为当前的最优切分变量 j j j和最优切分点 s s s,具体地,求解:
min ⁡ j , s [ min ⁡ c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + min ⁡ 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)}\left(y_{i}-c_{1}\right)^{2}+\min _{c_{2}} \sum_{x_{i} \in R_{2}(j, s)}\left(y_{i}-c_{2}\right)^{2}] j,smin[c1minxiR1(j,s)(yic1)2+c2minxiR2(j,s)(yic2)2]重复以上划分过程,直到满足停止条件为止,这样便形成了一棵回归树,这样的回归树通常称为最小二乘回归树。具体的算法步骤如下:

  1. 输入训练数据集 D D D;
  2. 遍历变量 j j j,求解:
    min ⁡ j , s [ min ⁡ c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + min ⁡ 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)}\left(y_{i}-c_{1}\right)^{2}+\min _{c_{2}} \sum_{x_{i} \in R_{2}(j, s)}\left(y_{i}-c_{2}\right)^{2}] j,smin[c1minxiR1(j,s)(yic1)2+c2minxiR2(j,s)(yic2)2]确定使得上式达到最小值的最优切分变量 j j j和最优切分点 s s s
  3. 用选定的最小值对 ( j , s ) (j, s) (j,s)划分区域并决定相应的输出值:
    R 1 ( j , s ) = { x ∣ x ( j ) ⩽ s } , R 2 ( j , s ) = { x ∣ x ( j ) > s } c ^ m = 1 N m ∑ x i ∈ R m ( j , s ) y i , x ∈ R m , m = 1 , 2 R_{1}(j, s)=\left\{x | x^{(j)} \leqslant s\right\}, \quad R_{2}(j, s)=\left\{x | x^{(j)}>s\right\}\\ \hat{c}_{m}=\frac{1}{N_{m}} \sum_{x_{i} \in R_{m}(j, s)} y_{i}, x \in R_{m}, \quad m=1,2 R1(j,s)={xx(j)s},R2(j,s)={xx(j)>s}c^m=Nm1xiRm(j,s)yi,xRm,m=1,2
  4. 继续对两个子区域调用步骤2、3,直至满足停止条件;
  5. 将输入空间h划分为 M M M区域 R 1 , R 2 , ⋯   , R M R_{1}, R_{2}, \cdots, R_{M} R1,R2,,RM,生成决策树:
    f ( x ) = ∑ m = 1 M c ^ m I ( x ∈ R m ) f(x)=\sum_{m=1}^{M} \hat{c}_{m} I\left(x \in R_{m}\right) f(x)=m=1Mc^mI(xRm)

    (二) 分类树的构造

    分类树则采用基尼指数选择最优特征,其算法步骤如下:

  1. 输入训练数据集D;
  2. 从根结点开始,计算现有特征 A A A取每个可能值 a a a时的基尼指数:
    Gini ⁡ ( D , A ) = ∣ D 1 ∣ ∣ D ∣ Gini ⁡ ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ Gini ⁡ ( D 2 ) \operatorname{Gini}(D, A)=\frac{\left|D_{1}\right|}{|D|} \operatorname{Gini}\left(D_{1}\right)+\frac{\left|D_{2}\right|}{|D|} \operatorname{Gini}\left(D_{2}\right) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)
  3. 选择基尼指数最小的特征及其对应的切分点作为最优特征和最优切分点,依最优特征和最优切分点,从现结点生成两个子结点,将训练集依特征分配到两个子结点中去;
  4. 对两个子结点递归地调用步骤2、3,直至满足停止条件为止;
  5. 生成CART决策树。
2.4.3 CART决策树的剪枝

    CART决策树的剪枝主要包含两个步骤:首先从生成的决策树 T 0 T_0 T0底端开始不断剪枝,直到 T 0 T_0 T0的根结点,形成一个子树序列 { T 0 , T 1 , ⋯   , T n } \left\{T_{0}, T_{1}, \cdots, T_{n}\right\} {T0,T1,,Tn};接着,通过交叉验证法在独立验证集上对子树序列进行测试,从中选择最优子树。

    从前面ID3算法我们可以知道,剪枝时的损失函数不仅考虑决策树对训练集的拟合程度,还考虑模型的复杂度,具体的公式如下:
C α ( T ) = C ( T ) + α ∣ T ∣ C_{\alpha}(T)=C(T)+\alpha|T| Cα(T)=C(T)+αTCART首先从整体树 T 0 T_0 T0开始剪枝,对 T 0 T_0 T0的任意内部结点 t t t,以t为单结点树的损失函数是:
C α ( t ) = C ( t ) + α C_{\alpha}(t)=C(t)+\alpha Cα(t)=C(t)+α t t t为根结点的子树 T t T_t Tt的损失函数是:
C α ( T t ) = C ( T t ) + α ∣ T t ∣ C_{\alpha}\left(T_{t}\right)=C\left(T_{t}\right)+\alpha\left|T_{t}\right| Cα(Tt)=C(Tt)+αTt C α ( T t ) = C α ( t ) C_{\alpha}\left(T_{t}\right)=C_{\alpha}(t) Cα(Tt)=Cα(t)时,即 α = C ( t ) − C ( T t ) ∣ T t ∣ − 1 \alpha=\frac{C(t)-C\left(T_{t}\right)}{\left|T_{t}\right|-1} α=Tt1C(t)C(Tt)时, T t T_{t} Tt t t t有相同的损失函数值,而 t t t的结点少,因此 t t t T t T_t Tt更可取,对 T t T_t Tt进行剪枝。

    因此,CART在剪枝时,对于 T 0 T_0 T0中每一内部结点 t t t,计算:
g ( t ) = C ( t ) − C ( T t ) ∣ T t ∣ − 1 g(t)=\frac{C(t)-C\left(T_{t}\right)}{\left|T_{t}\right|-1} g(t)=Tt1C(t)C(Tt) T 0 T_0 T0中减去 g ( t ) g(t) g(t)最小的 T t T_t Tt,将得到的子树作为 T 1 T_1 T1,同时将最小的 g ( t ) g(t) g(t)设为 α 1 \alpha_1 α1 T 1 T_1 T1为区间 [ α 1 , α 2 ) \left[\alpha_{1}, \alpha_{2}\right) [α1,α2)的最优子树,如此剪枝下去,直至根结点,在这一过程中,不断地增加 α \alpha α值,产生新的区间。
    最后,利用独立的验证数据集,测试子树序列 T 0 , T 1 , ⋯   , T n T_{0}, T_{1}, \cdots, T_{n} T0,T1,,Tn中各棵子树的平方误差或基尼指数,平方误差或基尼指数最小的子树即为最优的决策树,其所在的 α \alpha α区间即为最终 α \alpha α的取值。具体的剪枝算法步骤如下:

  1. 给定CART算法生成的决策树 T 0 T_0 T0,初始化k=0, α = + ∞ \alpha=+\infty α=+
  2. 自下而上地对各内部结点 t t t计算 C ( T t ) C\left(T_{t}\right) C(Tt) ∣ T t ∣ \left|T_{t}\right| Tt以及 g ( t ) = C ( t ) − C ( T t ) ∣ T t ∣ − 1 α = min ⁡ ( α , g ( t ) ) \begin{array}{c}{g(t)=\frac{C(t)-C\left(T_{t}\right)}{\left|T_{t}\right|-1}} \\ {\alpha=\min (\alpha, g(t))}\end{array} g(t)=Tt1C(t)C(Tt)α=min(α,g(t))其中, T t T_{t} Tt表示以 t t t为根结点的子树, C ( T t ) C(T_t) C(Tt)为对训练数据的预测误差, ∣ T t ∣ \left|T_{t}\right| Tt T t T_{t} Tt叶结点个数。
  3. 自上而下地访问内部结点 t t t,如果有 g ( t ) = α g(t)=\alpha g(t)=α,则进行剪枝,并对叶结点 t t t以多数表决法决定其类,得到树 T T T
  4. k = k + 1 , α k = α , T k = T k=k+1, \quad \alpha_{k}=\alpha, \quad T_{k}=T k=k+1,αk=α,Tk=T
  5. 如果 T T T不是由根结点单独构成的树,则回到步骤2
  6. 采用交叉验证法在子树序列 T 0 , T 1 , ⋯   , T n T_{0}, T_{1}, \cdots, T_{n} T0,T1,,Tn中选取最优子树 T α T_\alpha Tα

3. 常用决策树模型的python实现

    python中sklearn主要支持的是CART决策树,因为CART可适用的场景更广,不过,特征选择的准则sklearn也提供了两种选择,一种是“entropy”,对应本文介绍的信息增益,另一种是“gini”,对应本文的基尼指数,本文直接继承了sklearn.tree中的DecisionTreeClassifier,增加了对决策树的绘制函数,python绘制决策树需要安装graphviz,安装后如果出现中文乱码的话,可以参考这篇文章《graphviz Windows中文乱码》。具体的代码如下:

import os
from sklearn.tree import DecisionTreeClassifier, export_graphviz


class DecisionTreeClassifier(DecisionTreeClassifier):
    def draw_tree(self, model, feature_names, save_path):
        """
        绘制决策树
        :param model: 决策树模型
        :param feature_names: 结点名称. [list]
        :param save_path: 文件保存路径
        :return:
        """
        # 生成决策树的路径dot文件,保存到save_path
        export_graphviz(model, out_file=save_path,
                        feature_names=feature_names,
                        filled=True, rounded=True,
                        special_characters=True)

        # 替换dot文件中的字体为Microsoft YaHei,以防止中文乱码
        with open(save_path, 'r', encoding='utf-8') as f:
            dot_data = f.read()

        dot_data = dot_data.replace('fontname=helvetica', 'fontname="Microsoft YaHei"')

        with open(save_path, 'w', encoding='utf-8') as f:
            f.write(dot_data)

        # 生成决策树图像,格式默认为png格式
        os.system('dot -Tpng {0} -o {1}'.format(save_path, save_path.replace('dot', 'png')))

    绘制的决策树图形大致如下:
常用决策树模型介绍与python实现_第2张图片
具体的项目代码还是参考本人的github地址:

  • github地址:https://github.com/lch123456/machine-learning

4. 总结

    决策树由于其解释性强,计算速度快,非线性能力强,在一些对模型解释性强的行业得到了很多的应用,比如风控行业。另外,由于特征选择、决策树生成和决策树剪枝的不同,决策树衍生出了很多的算法,每个算法都有其对应的优缺点,因此,在使用时需要加以鉴别,比如ID3算法,由于不是二叉树的形式,因此该算法往往更倾向于选择类别多的特征。

你可能感兴趣的:(机器学习)