机器学习初级算法梳理三

任务三:决策树算法梳理

一、信息论基础

1.1 信息熵(Information Entropy)

熵 (entropy) 这一词最初来源于热力学。1948年,克劳德·爱尔伍德·香农将热力学中的熵引入信息论,所以也被称为香农熵 (Shannon entropy),信息熵 (information entropy)。本文只讨论信息熵。首先,我们先来理解一下信息这个概念。信息是一个很抽象的概念,百度百科将它定义为:指音讯、消息、通讯系统传输和处理的对象,泛指人类社会传播的一切内容。那信息可以被量化么?可以的!香农提出的“信息熵”概念解决了这一问题。

一条信息的信息量大小和它的不确定性有直接的关系。我们需要搞清楚一件非常非常不确定的事,或者是我们一无所知的事,就需要了解大量的信息。相反,如果我们对某件事已经有了较多的了解,我们就不需要太多的信息就能把它搞清楚。所以,从这个角度,我们可以认为,信息量的度量就等于不确定性的多少

考虑一个离散的随机变量 x x x,由上面两个例子可知,信息的量度应该依赖于概率分布 p ( x ) p(x) p(x),因此我们想要寻找一个函数 I ( x ) I(x) I(x),它是概率 p ( x ) p(x) p(x) 的单调函数,表达了信息的内容。怎么寻找呢?如果我们有两个不相关的事件 x x x y y y,那么观察两个事件同时发生时获得的信息量应该等于观察到事件各自发生时获得的信息之和,即:
I ( x , y ) = I ( x ) + I ( y ) I(x,y)=I(x)+I(y) I(x,y)=I(x)+I(y)

因为两个事件是独立不相关的,因此 p ( x , y ) = p ( x ) p ( y ) p(x,y)=p(x)p(y) p(x,y)=p(x)p(y)。根据这两个关系,很容易看出 I ( x ) I(x) I(x)一定与 p ( x ) p(x) p(x) 的对数有关 (因为对数的运算法则是 l o g a ( m n ) = l o g a m + l o g a n log_a(mn)=log_am+log_an loga(mn)=logam+logan)。因此,我们有

I ( x ) = − l o g p ( x ) I(x)=−logp(x) I(x)=logp(x)

其中负号是用来保证信息量是正数或者零。而 l o g log log 函数基的选择是任意的(信息论中基常常选择为2,因此信息的单位为比特bits;而机器学习中基常常选择为自然常数,因此单位常常被称为奈特nats)。 I ( x ) I(x) I(x) 也被称为随机变量 x x x 的自信息 (self-information),描述的是随机变量的某个事件发生所带来的信息量。图像如图:

最后,我们正式引出信息熵.现在假设一个发送者想传送一个随机变量的值给接收者。那么在这个过程中,他们传输的平均信息量可以通过求 I ( x ) = − l o g p ( x ) I(x)=−logp(x) I(x)=logp(x) 关于概率分布 p ( x ) p(x) p(x) 的期望得到,即:
H ( X ) = − ∑ x p ( x ) l o g p ( x ) = − ∑ i = 1 n p ( x i ) l o g p ( x i ) H(X)=-\sum_xp(x)logp(x)=-\sum_{i=1}^np(x_i)logp(x_i) H(X)=xp(x)logp(x)=i=1np(xi)logp(xi)

H ( X ) H(X) H(X) 就被称为随机变量 x x x熵,它是表示随机变量不确定的度量,是对所有可能发生的事件产生的信息量的期望。

注意点:

  1. 熵只依赖于随机变量的分布,与随机变量取值无关,所以也可以将 X X X 的熵记作 H ( p ) H(p) H(p)
  2. 0 l o g 0 = 0 0log0=0 0log0=0 (因为某个取值概率可能为0)。

从公式可得,随机变量的取值个数越多,状态数也就越多,信息熵就越大,混乱程度就越大。当随机分布为均匀分布时,熵最大,且 0 ≤ H ( X ) ≤ l o g n 0≤H(X)≤logn 0H(X)logn

1.2 联合熵(Joint entropy)

将一维随机变量分布推广到多维随机变量分布,其联合熵为:
H ( X , Y ) = − ∑ x , , y p ( x , y ) l o g p ( x , y ) = − ∑ i = 1 n ∑ j = 1 m p ( x i , y i ) l o g p ( x i , y i ) H(X,Y)=-\sum_{x,,y}p(x,y)logp(x,y)=-\sum_{i=1}^n\sum_{j=1}^mp(x_i,y_i)logp(x_i,y_i) H(X,Y)=x,,yp(x,y)logp(x,y)=i=1nj=1mp(xi,yi)logp(xi,yi)

1.3 条件熵(Conditional entropy)

条件熵 H ( Y ∣ X ) H(Y|X) H(YX)表示在已知随机变量 X X X的条件下随即变量 Y Y Y的不确定性。条件熵 H ( Y ∣ X ) H(Y|X) H(YX)定义为 X X X给定条件下 Y Y Y的条件概率分布的熵对 X X X的数学期望:

条件熵 H ( Y ∣ X ) H(Y|X) H(YX) 相当于联合熵 H ( X , Y ) H(X,Y) H(X,Y) 减去单独的熵 H ( X ) H(X) H(X),即

H ( Y ∣ X ) = H ( X , Y ) − H ( X ) H(Y|X)=H(X,Y)−H(X) H(YX)=H(X,Y)H(X),证明如下:

举个例子,比如环境温度是低还是高,和我穿短袖还是外套这两个事件可以组成联合概率分布 H ( X , Y ) H(X,Y) H(X,Y),因为两个事件加起来的信息量肯定是大于单一事件的信息量的。假设 H ( X ) H(X) H(X) 对应着今天环境温度的信息量,由于今天环境温度和今天我穿什么衣服这两个事件并不是独立分布的,所以在已知今天环境温度的情况下,我穿什么衣服的信息量或者说不确定性是被减少了。当已知 H ( X ) H(X) H(X) 这个信息量的时候, H ( X , Y ) H(X,Y) H(X,Y) 剩下的信息量就是条件熵:

H ( Y ∣ X ) = H ( X , Y ) − H ( X ) H(Y|X)=H(X,Y)−H(X) H(YX)=H(X,Y)H(X)

因此,可以这样理解,描述 X X X Y Y Y 所需的信息是描述 X X X 自己所需的信息,加上给定 X X X 的条件下具体化 Y Y Y 所需的额外信息,如下图所示。

1.3 相对熵(Relative entropy)

p ( x ) p(x) p(x) q ( x ) q(x) q(x) 是离散随机变量 X X X 中取值的两个概率分布,则 p p p q q q 的相对熵是:
D K L ( p ∥ q ) = ∑ x p ( x ) l o g ( p ( x ) q ( x ) ) D_{KL}(p\parallel q)=\sum_xp(x)log(\frac{p(x)}{q(x)}) DKL(pq)=xp(x)log(q(x)p(x))

性质:

  1. 如果 p(x) 和 q(x) 两个分布相同,那么相对熵等于0
  2. DKL(p||q)≠DKL(q||p) ,相对熵具有不对称性。大家可以举个简单例子算一下。
  3. DKL(p||q)≥0

相对熵可以用来衡量两个概率分布之间的差异,上面公式的意义就是求 p p p q q q 之间的对数差在 p p p 上的期望值。

1.4 交叉熵(Cross entropy)

现在有关于样本集的两个概率分布 p ( x ) p(x) p(x) q ( x ) q(x) q(x),其中 p ( x ) p(x) p(x) 为真实分布, q ( x ) q(x) q(x) 非真实分布。如果用真实分布 p ( x ) p(x) p(x) 来衡量识别别一个样本所需要编码长度的期望(平均编码长度)为:
H ( p ) = − ∑ x p ( x ) l o g ( p ( x ) ) H(p)=-\sum_xp(x)log(p(x)) H(p)=xp(x)log(p(x))

如果使用非真实分布 q ( x ) q(x) q(x) 来表示来自真实分布 p ( x ) p(x) p(x) 的平均编码长度,则是:

H ( p , q ) = ∑ x p ( x ) l o g 1 q ( x ) H(p,q)=\sum_xp(x)log{\frac{1}{q(x)}} H(p,q)=xp(x)logq(x)1。(因为用 q ( x ) q(x) q(x) 来编码的样本来自于分布 q ( x ) q(x) q(x) ,所以 H ( p , q ) H(p,q) H(p,q) 中的概率是 p ( x ) p(x) p(x))。此时就将 H ( p , q ) H(p,q) H(p,q) 称之为交叉熵。举个例子。考虑一个随机变量 x,真实分布 p ( x ) = ( 1 2 , 1 4 , 1 8 , 1 8 ) p(x)=(\frac{1}{2},\frac{1}{4},\frac{1}{8},\frac{1}{8}) p(x)=(21,41,81,81),非真实分布 p ( x ) = ( 1 4 , 1 4 , 1 4 , 1 4 ) p(x)=(\frac{1}{4},\frac{1}{4},\frac{1}{4},\frac{1}{4}) p(x)=(41,41,41,41), 则 H ( p ) = 1.75 b i t s H(p)=1.75 bits H(p)=1.75bits(最短平均码长),交叉熵 H ( p , q ) = 1 2 l o g 2 4 + 1 4 l o g 2 4 + 1 8 l o g 2 4 + 1 8 l o g 2 4 = 2 b i t s H(p,q)=\frac{1}{2}log_24+\frac{1}{4}log_24+\frac{1}{8}log_24+\frac{1}{8}log_24=2 bits H(p,q)=21log24+41log24+81log24+81log24=2bits。由此可以看出根据非真实分布 q ( x ) q(x) q(x) 得到的平均码长大于根据真实分布 p ( x ) p(x) p(x) 得到的平均码长。

我们再化简一下相对熵的公式。

D K L ( p ∥ q ) = ∑ x p ( x ) l o g ( p ( x ) q ( x ) ) = ∑ x p ( x ) l o g p ( x ) − p ( x ) l o g q ( x ) D_{KL}(p\parallel q)=\sum_xp(x)log(\frac{p(x)}{q(x)})=∑xp(x)logp(x)−p(x)logq(x) DKL(pq)=xp(x)log(q(x)p(x))=xp(x)logp(x)p(x)logq(x)

熵的公式 :
H ( p ) = − ∑ x p ( x ) l o g p ( x ) H(p)=−∑_xp(x)logp(x) H(p)=xp(x)logp(x)

交叉熵的公式
H ( p , q ) = ∑ x p ( x ) l o g 1 q ( x ) = − ∑ x p ( x ) l o g q ( x ) H(p,q)=∑_xp(x)log\frac{1}{q(x)}=−∑_xp(x)logq(x) H(p,q)=xp(x)logq(x)1=xp(x)logq(x)

所以有:

D K L ( p ∣ ∣ q ) = H ( p , q ) − H ( p ) D_{KL}(p||q)=H(p,q)−H(p) DKL(pq)=H(p,q)H(p)(当用非真实分布 q ( x ) q(x) q(x) 得到的平均码长比真实分布 p ( x ) p(x) p(x) 得到的平均码长多出的比特数就是相对熵)

又因为 D K L ( p ∣ ∣ q ) ≥ 0 D_{KL}(p||q)≥0 DKL(pq)0

所以 H ( p , q ) ≥ H ( p ) H(p,q)≥H(p) H(p,q)H(p)(当 p ( x ) = q ( x ) p(x)=q(x) p(x)=q(x) 时取等号,此时交叉熵等于信息熵)

并且当 H ( p ) H(p) H(p) 为常量时(注:在机器学习中,训练数据分布是固定的),最小化相对熵 D K L ( p ∣ ∣ q ) D_KL(p||q) DKL(pq) 等价于最小化交叉熵 H ( p , q ) H(p,q) H(p,q) 也等价于最大化似然估计

1.5 信息增益(Cross entropy)

我们把特征A对数据集D的信息增益记为 g(X ,A) ,定义集合D的信息熵为 (X),定义集合D在特征A条件下的条件熵为 H(X|A),那么信息增益为:

g ( X , A ) = H ( X ) − H ( X ∣ A ) g(X,A)=H(X)−H(X∣A) g(X,A)=H(X)H(XA)

信息增益表示在条件A确定的情况下,信息的不确定性减少的程度。也就是说按照条件A对数据进行分类之后,分类数据的确定性是否比划分之前更高。因此我们可以通过计算信息增益来选择使用哪个特征作为决策树的节点更合适。

缺点:信息增益偏向取值较多的特征(原因:当特征的取值较多时,根据此特征划分更容易得到纯度更高的子集,因此划分后的熵更低,即不确定性更低,因此信息增益更大)

1.6 基尼不纯度(Gini purity)

基尼不纯度:将来自集合的某种结果随机应用于某一数据项的预期误差率。
I G ( p ) = ∑ i 1 m p i ( 1 − p i ) = ∑ i 1 m p i − ∑ i 1 m p i 2 = 1 − ∑ i 1 m p i 2 IG(p)=∑_i\frac{1}{m}p_i(1−p_i)=∑_i\frac{1}{m}pi−∑_i\frac{1}{m}p^2_i=1−∑_i\frac{1}{m}p^2_i IG(p)=im1pi(1pi)=im1piim1pi2=1im1pi2

(1)显然基尼不纯度越小,纯度越高,集合的有序程度越高,分类的效果越好;

(2)基尼不纯度为 0 时,表示集合类别一致;

(3)基尼不纯度最高(纯度最低)时, p 1 = p 2 = … = p m = 1 m p_1=p_2=…=p_m=\frac{1}{m} p1=p2==pm=m1

I G ( f ) = 1 − ( 1 m ) 2 × m = 1 − 1 m IG(f)=1−(\frac{1}{m})^2×m=1−\frac{1}{m} IG(f)=1(m1)2×m=1m1

二、决策树的不同分类算法的原理及应用场景

2.1 ID3算法

原理:计算使用所有特征划分数据集D,得到多个特征划分数据集D的信息增益,从这些信息增益中选择最大的,因而当前结点的划分特征便是使信息增益最大的划分所使用的特征。只支持离散的特征属性。

算法步骤:

输入:训练数据集D,特征集A,阈值ε;

输出:决策树T.

Step1:若D中所有实例属于同一类,则T为单结点树,并将类作为该节点的类标记,返回T;

Step2:若A=Ø,则T为单结点树,并将D中实例数最大的类作为该节点的类标记,返回T;

Step3:否则,计算A中个特征对D的信息增益,选择信息增益最大的特征;

Step4:如果的信息增益小于阈值ε,则T为单节点树,并将D中实例数最大的类作为该节点的类标记,返回T

Step5:否则,对的每一种可能值,依将D分割为若干非空子集,将中实例数最大的类作为标记,构建子结点,由结点及其子树构成树T,返回T;

Step6:对第i个子节点,以为训练集,以为特征集合,递归调用Step1~step5,得到子树,返回;

缺点:当特征的取值较多时,根据此特征划分更容易得到纯度更高的子集,因此划分之后的熵更低,由于划分前的熵是一定的,因此信息增益更大,因此信息增益比较偏向取值较多的特征。

2.2 C4.5算法

C4.5算法与ID3算法很相似,C4.5算法是对ID3算法做了改进,在生成决策树过程中采用信息增益比来选择特征。

信息增益比

我们知道信息增益会偏向取值较多的特征,使用信息增益比可以对这一问题进行校正。

定义:特征A对训练数据集D的信息增益比GainRatio(D,A)定义为其信息增益Gain(D,A)与训练数据集D的经验熵H(D)之比:

算法步骤:

C4.5算法过程跟ID3算法一样,只是选择特征的方法由信息增益改成信息增益比。

2.3 CART算法

Gini指数

对于给定的样本集合D,其基尼指数为:

备注:这里是D中属于第k类的样本自己,K是类的个数。

基尼指数Gini(D)表示集合D的不确定性,基尼指数Gini(D,A)表示经A=a分割后集合D的不确定性。基尼指数值越大,样本集合的不确定性也就越大,这一点跟熵相似。

下面举一个例子来说明上面的公式:

如下,是一个包含30个学生的样本,其包含三种特征,分别是:性别(男/女)、班级(IX/X)和高度(5到6ft)。其中30个学生里面有15个学生喜欢在闲暇时间玩板球。那么要如何选择第一个要划分的特征呢,我们通过上面的公式来进行计算。

如下,可以Gini(D,Gender)最小,所以选择性别作为最优特征。

算法步骤

输入:训练数据集D,停止计算的条件

输出:CART决策树

根据训练数据集,从根结点开始,递归地对每个结点进行以下操作,构建二叉树:

Step1:设结点的训练数据集为D,计算现有特征对该数据集的基尼指数。此时,对每一个特征A,对其可能取的每个值a,根据样本点A=a的测试为“是”或“否”将D分割为D1和D2两部分,利用上式Gini(D,A)来计算A=a时的基尼指数。

Step2:在所有可能的特征A以及他们所有可能的切分点a中,选择基尼指数最小的特征及其对应可能的切分点作为最有特征与最优切分点。依最优特征与最有切分点,从现结点生成两个子节点,将训练数据集依特征分配到两个子节点中去。

Step3:对两个子结点递归地调用Step1、Step2,直至满足条件。

Step4:生成CART决策树

算法停止计算的条件是节点中的样本个数小于预定阈值,或样本集的基尼指数小于预定阈值,或者没有更多特征。

三、回归树原理

回归树是可以用于回归的决策树模型,**一个回归树对应着输入空间(即特征空间)的一个划分以及在划分单元上的输出值。**与分类树不同的是,回归树对输入空间的划分采用一种启发式的方法,会遍历所有输入变量,找到最优的切分变量j和最优的切分点s,即选择第j个特征 x j x^j xj和它的取值s将输入空间划分为两部分,然后重复这个操作。

而如何找到最优的j和s是通过比较不同的划分的误差来得到的。一个输入空间的划分的误差是用真实值和划分区域的预测值的最小二乘来衡量的,即:
∑ x i ∈ R m ( y i − f ( x i ) ) 2 ∑_{xi∈R_m}(y_i−f(x_i))^2 xiRm(yif(xi))2

其中, f ( x i ) f(x_i) f(xi)是每个划分单元的预测值,这个预测值是该单元内每个样本点的值的均值,即
f ( x i ) = c m = a v e ( y i ∣ x i ∈ R m ) f(x_i)=cm=ave(y_i|x_i∈R_m) f(xi)=cm=ave(yixiRm)

(将输入空间划分为M个单元 R 1 , R 2 , . . . , R m R_1,R_2,...,R_m R1,R2,...,Rm)
那么,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}∑_{x_i∈R_1(j,s)}(yi−c_1)^2+min_{c_2}∑_{x_i∈R_2(j,s)}(yi−c_2)^2] minj,s[minc1xiR1(j,s)(yic1)2+minc2xiR2(j,s)(yic2)2]

其中, R 1 ( j , s ) = x ∣ x j ≤ s 和 R 2 ( j , s ) = x ∣ x j > s R_1(j,s)= {x|x_j≤s}和R_2(j,s)= {x|x_j>s} R1(j,s)=xxjsR2(j,s)=xxj>s是被划分后的两个区域

梳理一下上述内容,最小二乘回归树的生成方法如下:

  1. 选择最优的切分变量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}∑_{x_i∈R_1(j,s)}(yi−c_1)^2+min_{c_2}∑_{x_i∈R_2(j,s)}(yi−c_2)^2] minj,s[minc1xiR1(j,s)(yic1)2+minc2xiR2(j,s)(yic2)2]
    遍历所有特征,对固定的特征扫描所有取值,找到使上式达到最小值的对(j,s).
  2. 用选定的对 (j,s)划分区域,并确定该区域的预测值;
  3. 继续对两个字区域调用上述步骤,直至满足停止条件;
  4. 生成回归树;

四、决策树防止过拟合手段

上文提到的决策树算法生成的决策树非常详细并且庞大,每个属性都被详细地加以考虑,决策树的树叶节点所覆盖的训练样本都是“纯”的。因此用这个决策树来对训练样本进行分类的话,你会发现对于训练样本而言,这个树表现完好,误差率极低且能够正确得对训练样本集中的样本进行分类。训练样本中的错误数据也会被决策树学习,成为决策树的部分,但是对于测试数据的表现就没有想象的那么好,或者极差,这就是所谓的过拟合(Overfitting)问题。

4.1 决策树的剪枝

决策树的剪枝有两种思路:预剪枝(Pre-Pruning)和后剪枝(Post-Pruning)

预剪枝(Pre-Pruning)

在构造决策树的同时进行剪枝。所有决策树的构建方法,都是在无法进一步降低熵的情况下才会停止创建分支的过程,为了避免过拟合,可以设定一个阈值,熵减小的数量小于这个阈值,即使还可以继续降低熵,也停止继续创建分支。但是这种方法实际中的效果并不好。

后剪枝(Post-Pruning)

决策树构造完成后进行剪枝。剪枝的过程是对拥有同样父节点的一组节点进行检查,判断如果将其合并,熵的增加量是否小于某一阈值。如果确实小,则这一组节点可以合并一个节点,其中包含了所有可能的结果。后剪枝是目前最普遍的做法。 后剪枝的剪枝过程是删除一些子树,然后用其叶子节点代替,这个叶子节点所标识的类别通过大多数原则(majority class criterion)确定。所谓大多数原则,是指剪枝过程中, 将一些子树删除而用叶节点代替,这个叶节点所标识的类别用这棵子树中大多数训练样本所属的类别来标识,所标识的类 称为majority class ,(majority class 在很多英文文献中也多次出现)。

4.2 后剪枝算法

后剪枝算法有很多种,这里简要总结如下:

Reduced-Error Pruning (REP,错误率降低剪枝)

这个思路很直接,完全的决策树不是过度拟合么,我再搞一个测试数据集来纠正它。对于完全决策树中的每一个非叶子节点的子树,我们尝试着把它替换成一个叶子节点,该叶子节点的类别我们用子树所覆盖训练样本中存在最多的那个类来代替,这样就产生了一个简化决策树,然后比较这两个决策树在测试数据集中的表现,如果简化决策树在测试数据集中的错误比较少,那么该子树就可以替换成叶子节点。该算法以bottom-up的方式遍历所有的子树,直至没有任何子树可以替换使得测试数据集的表现得以改进时,算法就可以终止。

Pessimistic Error Pruning (PEP,悲观剪枝)

PEP剪枝算法是在C4.5决策树算法中提出的, 把一颗子树(具有多个叶子节点)用一个叶子节点来替代(我研究了很多文章貌似就是用子树的根来代替)的话,比起REP剪枝法,它不需要一个单独的测试数据集。

PEP算法首先确定这个叶子的经验错误率(empirical)为(E+0.5)/N,0.5为一个调整系数。对于一颗拥有L个叶子的子树,则子树的错误数和实例数都是就应该是叶子的错误数和实例数求和的结果,则子树的错误率为e,这个e后面会用到。

然后用一个叶子节点替代子树,该新叶子节点的类别为原来子树节点的最优叶子节点所决定(这句话是从一片论文看到的,但是论文没有讲什么是最优,通过参考其他文章,貌似都是把子树的根节点作为叶子,也很形象,就是剪掉所有根以下的部分),J为这个替代的叶子节点的错判个数,但是也要加上0.5,即KJ+0.5。最终是否应该替换的标准为:
被 替 换 子 树 的 错 误 数 − 标 准 差 > 新 叶 子 错 误 数 被替换子树的错误数-标准差 > 新叶子错误数 >

出现标准差,是因为我们的子树的错误个数是一个随机变量,经过验证可以近似看成是二项分布,就可以根据二项分布的标准差公式算出标准差,就可以确定是否应该剪掉这个树枝了。子树中有N的实例,就是进行N次试验,每次实验的错误的概率为e,符合B(N,e)的二项分布,根据公式,均值为Ne,方差为Ne(1-e),标准差为方差开平方。

五、模型评估

常用的评估分类器性能的方法:

1、保持方法

在保持(Holdout)方法中,将被标记的原始数据划分成两个不想交的集合,分别称为训练集合检验集。在训练数据集上归纳分类模型,在检验集上评估模型的性能。训练集和检验集的划分比例通常根据分析家的判断(例如,50-50,或者2/3作为训练集、1/3作为检验集)。分类器的准确率根据模型在检验集上的准确率估计。

2、随机二次抽样

可以多次重复保持方法来改进对分类器性能的估计,这种方法称作随机二次抽样(random subsampling)。设 a c c i acc_i acci是第i次迭代的模型准确率,总准确率是 a c c s u b = ∑ i = 1 k a c c i / k acc_{sub}=∑_{i=1}^k acc_i/k accsub=i=1kacci/k。随机二次抽样也会遇到一些与保持方法同样的问题,因为在训练阶段也没有利用尽可能多的数据。并且,由于它没有控制每个记录用于训练和检验的次数,因此,有些用于训练的记录使用的频率可能比其他记录高很多。

3、交叉验证

替代随机二次抽样的一种方法是交叉验证(cross-validation)。在该方法中,每个记录用于训练的次数相同,并且恰好检验一次。为了解释该方法,假设把数据分为相同大小的两个子集,首先,我们选择一个子集作训练集,而另一个作检验集,然后交换两个集合的角色,原先作训练集的现在做检验集,反之亦然,这种方法叫做二折交叉验证。总误差通过对两次运行的误差求和得到。在这个例子中,每个样本各作一次训练样本和检验样本。k折交叉验证是对该方法的推广,把数据分为大小相同的k份,在每次运行,选择其中一份作检验集,而其余的全作为训练集,该过程重复k次,使得每份数据都用于检验恰好一次。同样,总误差是所有k次运行的误差之和。

4、自助法

以上方法都是假定训练记录采用不放回抽样,因此,训练集合检验集都不包含重复记录。在自助(bootstrap)方法中,训练记录采用有放回抽样,即已经选作训练的记录将放回原来的记录集中,使得它等机率地被重新抽取。如果原始数据有N个记录,可以证明,平均来说,大小为N的自助样本大约包含原始数据中63.2%的记录。这是因为一个记录被自助抽样抽取的概率是 1 − ( 1 − 1 / N ) N 1−(1−1/N)^N 1(11/N)N,当N充分大时,该概率逐渐逼近1−e−1=0.632。没有抽中的记录就成为检验集的一部分,将训练集建立的模型应用到检验集上,得到自助样本准确率的一个估计εi。抽样过程重复b次,产生b个自助样本。

按照如何计算分类器的总准确率,有几种不同的自助抽样法。常用的方法之一是.632自助(.632 bootstrap),它通过组合每个自助样本的准确率( ε i ε_i εi)和由包含所有标记样本的训练集计算的准确率( a c c s acc_s accs)计算总准确率( a c c b o o t acc_boot accboot):

a c c b o o t = 1 b ∑ i = 1 b ( 0.632 × ε i + 0.368 × a c c s ) acc_{boot}=\frac{1}{b}∑_i=\frac{1}{b}(0.632×ε_i+0.368×acc_s) accboot=b1i=b1(0.632×εi+0.368×accs)

六、sklearn参数详解,Python绘制决策树

scikit-learn决策树算法类库内部实现是使用了调优过的CART树算法,既可以做分类,又可以做回归。分类决策树的类对应的是DecisionTreeClassifier,而回归决策树的类对应的是DecisionTreeRegressor。两者的参数定义几乎完全相同,但是意义不全相同。下面就对DecisionTreeClassifier和DecisionTreeRegressor的重要参数做一个总结,重点比较两者参数使用的不同点和调参的注意点。

6.1 DecisionTreeClassifier和DecisionTreeRegressor 重要参数调参注意点

为了便于比较,这里我们用表格的形式对DecisionTreeClassifier和DecisionTreeRegressor重要参数要点做一个比较。

参数DecisionTreeClassifierDecisionTreeRegressor
特征选择标准criterion可以使用"gini"或者"entropy",前者代表基尼系数,后者代表信息增益。一般说使用默认的基尼系数"gini"就可以了,即CART算法。除非你更喜欢类似ID3, C4.5的最优特征选择方法。可以使用"mse"或者"mae",前者是均方差,后者是和均值之差的绝对值之和。推荐使用默认的"mse"。一般来说"mse"比"mae"更加精确。除非你想比较二个参数的效果的不同之处。
特征划分点选择标准splitter可以使用"mse"或者"mae",前者是均方差,后者是和均值之差的绝对值之和。推荐使用默认的"mse"。一般来说"mse"比"mae"更加精确。除非你想比较二个参数的效果的不同之处。同DecisionTreeClassifier
划分时考虑的最大特征数max_features可以使用很多种类型的值,默认是"None",意味着划分时考虑所有的特征数;如果是"log2"意味着划分时最多考虑 l o g 2 N log_2N log2N个特征;如果是"sqrt"或者"auto"意味着划分时最多考虑 N \sqrt{N} N 个特征。如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。一般来说,如果样本特征数不多,比如小于50,我们用默认的"None"就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。同DecisionTreeClassifier
决策树最大深max_depth决策树的最大深度,默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。同DecisionTreeClassifier
内部节点再划分所需最小样本数min_samples_split这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。我之前的一个项目例子,有大概10万样本,建立决策树时,我选择了min_samples_split=10。可以作为参考。同DecisionTreeClassifier
叶子节点最少样本数min_samples_leaf这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。之前的10万样本项目使用min_samples_leaf的值为5,仅供参考。同DecisionTreeClassifier
叶子节点最小的样本权重和min_weight_fraction_leaf这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。同DecisionTreeClassifier
最大叶子节点数max_leaf_nodes通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。同DecisionTreeClassifier
类别权重class_weight指定样本各类别的的权重,主要是为了防止训练集某些类别的样本过多,导致训练的决策树过于偏向这些类别。这里可以自己指定各个样本的权重,或者用“balanced”,如果使用“balanced”,则算法会自己计算权重,样本量少的类别所对应的样本权重会高。当然,如果你的样本类别分布没有明显的偏倚,则可以不管这个参数,选择默认的"None"不适用于回归树
节点划分最小不纯度min_impurity_split这个值限制了决策树的增长,如果某节点的不纯度(基尼系数,信息增益,均方差,绝对差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。同DecisionTreeClassifier
数据是否预排序presort这个值是布尔值,默认是False不排序。一般来说,如果样本量少或者限制了一个深度很小的决策树,设置为true可以让划分点选择更加快,决策树建立的更加快。如果样本量太大的话,反而没有什么好处。问题是样本量少的时候,我速度本来就不慢。所以这个值一般懒得理它就可以了。同DecisionTreeClassifier

除了这些参数要注意以外,其他在调参时的注意点有:

  1. 当样本少数量但是样本特征非常多的时候,决策树很容易过拟合,一般来说,样本数比特征数多一些会比较容易建立健壮的模型
  2. 如果样本数量少但是样本特征非常多,在拟合决策树模型前,推荐先做维度规约,比如主成分分析(PCA),特征选择(Losso)或者独立成分分析(ICA)。这样特征的维度会大大减小。再来拟合决策树模型效果会好。
  3. 推荐多用决策树的可视化(下节会讲),同时先限制决策树的深度(比如最多3层),这样可以先观察下生成的决策树里数据的初步拟合情况,然后再决定是否要增加深度。
  4. 在训练模型先,注意观察样本的类别情况(主要指分类树),如果类别分布非常不均匀,就要考虑用class_weight来限制模型过于偏向样本多的类别。
  5. 决策树的数组使用的是numpy的float32类型,如果训练数据不是这样的格式,算法会先做copy再运行。
  6. 如果输入的样本矩阵是稀疏的,推荐在拟合前调用csc_matrix稀疏化,在预测前调用csr_matrix稀疏化。

6.2 决策树可视化

策树可视化化可以方便我们直观的观察模型,以及发现模型中的问题。这里介绍下scikit-learn中决策树的可视化方法。

6.2.1 决策树可视化环境搭建

scikit-learn中决策树的可视化一般需要安装graphviz。主要包括graphviz的安装和python的graphviz插件的安装。

第一步是安装graphviz。下载地址在:http://www.graphviz.org/ 如果你是linux,可以用apt-get或者yum的方法安装。如果是windows,就在官网下载msi文件安装。无论是linux还是windows,装完后都要设置环境变量,将graphviz的bin目录加到PATH。

第二步是安装python插件graphviz: pip install graphviz

第三步是安装python插件pydotplus。这个没有什么好说的: pip install pydotplus

6.2.2 决策树可视化三种方法

这里我们有一个例子讲解决策树可视化。

首先载入类库:

from sklearn.datasets import load_iris
from sklearn import tree
import sys
import os       

接着载入sciki-learn的自带数据,有决策树拟合,得到模型:

iris = load_iris()
clf = tree.DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)

现在可以将模型存入dot文件iris.dot。

with open("iris.dot", 'w') as f:
    f = tree.export_graphviz(clf, out_file=f)

这时候我们有3种可视化方法,第一种是用graphviz的dot命令生成决策树的可视化文件,敲完这个命令后当前目录就可以看到决策树的可视化文件iris.pdf.打开可以看到决策树的模型图。

#注意,这个命令在命令行执行
dot -Tpdf iris.dot -o iris.pdf

第二种方法是用pydotplus生成iris.pdf。这样就不用再命令行去专门生成pdf文件了。

import pydotplus 
dot_data = tree.export_graphviz(clf, out_file=None) 
graph = pydotplus.graph_from_dot_data(dot_data) 
graph.write_pdf("iris.pdf") 

第三种办法是个人比较推荐的做法,因为这样可以直接把图产生在ipython的notebook。代码如下:

from IPython.display import Image  
dot_data = tree.export_graphviz(clf, out_file=None, 
                         feature_names=iris.feature_names,  
                         class_names=iris.target_names,  
                         filled=True, rounded=True,  
                         special_characters=True)  
graph = pydotplus.graph_from_dot_data(dot_data)  
Image(graph.create_png()) 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值