1 前文

1.1 决策树基础知识

Key points:

  • 决策树是一个分类算法,分类结果是离散值(对应输出结果是连续值的回归算法);
  • 有监督的分类算法;
  • 是一种贪婪算法,生成的每一步都是局部最优值
  • 容易over fitting
  • noise影响不大
  • 空间划分,通过递归的方法把特征空间划分成不重叠的矩形

如何处理过拟合
Pre-pruning

  • 设定一个阈值,该阈值可以是决策树高度,节点实例个数,信息增益值等,该节点成为叶节点
  • 叶节点持有其数据集中样本最多的类或者其概率分布

Post-pruning
首先构造完整的决策树,允许决策树过度拟合训练数据,对置信度不够的节点的子树用叶节点或树枝来替代,该叶节点持有其子树的数据集中样本最多的类或者其概率分布

什么时候需要剪枝
数据噪音,因此有的分类不准
训练数据量少,或者不具有代表性
过拟合

1.2 算法对比

ID3
1979年JR.Quilan给出ID3算法,并在1983年和1986年对DI3进行了总结和简化,使其成为决策树学习算法的典型。选择具有最高信息增益的属性作为测试属性,Schlimmer 和Fisher 于1986年对ID3进行改造,在每个可能的决策树节点创建缓冲区,使决策树可以递增式生成,得到ID4算法。1988年,Utgoff 在ID4基础上提出了ID5学习算法,进一步提高了效率。

Entropy(S)=plog2ppΘlog2pΘ Entropy(S)=-{{p}_{\oplus }}lo{{g}_{2}}{{p}_{\oplus }}-{{p}_{\Theta }}lo{{g}_{2}}{{p}_{\Theta }}

pp_\oplus代表正样本,pΘp_\Theta代表负样本
C4.5
1993年 Quinlan 进一步发展了ID3算法,改进成C4.5算法。
信息增益率information gain ratio
连续值属性离散化处理:将连续型的属性变量进行离散化处理,形成决策树的训练集
把需要处理的样本按照连续变量的大小从小到大进行排序,假设该属性对应的不同的属性值一共有N个,那么总共有N-1个可能的候选分割阈值点,每个候选的分割阈值点的值为上述排序后的属性值中两两前后元素的中点
用信息增益率选择最佳划分
缺失值
处理缺少属性值的一种策略是赋给它节点t所对应的训练实例中该属性的最常见值
复杂一点的办法是为每个可能值赋一个概率
最简单的办法是丢弃这些样本
后剪枝(基于错误剪枝EBP-Error Based Pruning)

C5.0
1998年加入了Boosting算法框架
CART (Classification and Regression Trees)
另一类决策树算法为CART,与C4.5不同的是,CART的决策树由二元逻辑问题生成,每个树节点只有两个分枝,分别包括学习实例的正例与反例,引入基尼系数

2 ID3

2.1 ID算法描述

ID3算法是决策树算法的一种。想了解什么是ID3算法之前,我们得先明白一个概念:奥卡姆剃刀。
奥卡姆剃刀(Occam’s Razor, Ockham’s Razor),又称“奥坎的剃刀”,是由14世纪逻辑学家、圣方济各会修士奥卡姆的威廉(William of Occam,约1285年至1349年)提出,他在《箴言书注》2卷15题说“切勿浪费较多东西,去做‘用较少的东西,同样可以做好的事情’。简单点说,便是:be simple。
ID3算法 Iterative Dichotomiser 3迭代二叉树3代 是一个由Ross Quinlan(1975)发明的用于决策树的算法。这个算法便是建立在上述所介绍的奥卡姆剃刀的基础上:越是小型的决策树越优于大的决策树(be simple简单理论)。尽管如此,该算法也不是总是生成最小的树形结构,而是一个启发式算法。
从信息论知识中我们知道,期望信息越小,信息增益越大,从而纯度越高 。ID3算法的核心思想就是以信息增益度量属性选择,选择分裂后信息增益(很快,由下文你就会知道信息增益又是怎么一回事)最大的属性进行分裂。该算法采用自顶向下的贪婪搜索遍历可能的决策树空间。
所以,ID3的思想便是:选择具有最高信息增益的属性作为测试属性

ID3(DataSet, featureList):——DataSet为样本数据集, featureList为特征列表
创建根节点R
若当前DataSet中的数据都属于同一类,则标记R的类别为该类
若当前featureList集合为空,则标记R的类别为当前DataSet中样本最多的类别
递归情况:
  从featureList中选择属性(选择Gani(DataSet,F)最大的属性)
  根据F的每一个值v,将DataSet划分为不同的子集DS,对每一个Ds:
    创建节点C
    如果DS为空,节点C标记为DataSet中样本最多的类别
    如果DS不为空,节点C=ID3( DS,featureList-F )
    将节点C添加为R的子节点

2.2 信息熵(entropy)

上文中,我们提到:“ID3算法的核心思想就是以信息增益度量属性选择,选择分裂后信息增益(很快,由下文你就会知道信息增益又是怎么一回事)最大的属性进行分裂。”接下来,咱们就来看看这个信息增益是个什么概念(当然,在了解信息增益之前,你必须先理解:信息增益的度量标准:熵)。
上述的ID3算法的核心问题是选取在树的每个结点要测试的属性。我们希望选择的是最有利于分类实例的属性,信息增益(Information Gain)是用来衡量给定的属性区分训练样例的能力,而ID3算法在增长树的每一步使用信息增益从候选属性中选择属性。

为了精确地定义信息增益,我们先定义信息论中广泛使用的一个度量标准,称为熵,它刻画了任意样例集的纯度(purity)。给定包含关于某个目标概念的正反样例的样例集S,那么S相对这个布尔型分类的熵为:

Entropy(S)=plog2ppΘlog2pΘ Entropy(S)=-{{p}_{\oplus }}lo{{g}_{2}}{{p}_{\oplus }}-{{p}_{\Theta }}lo{{g}_{2}}{{p}_{\Theta }}

pp_\oplus代表正样本,pΘp_\Theta代表负样本,比如在本文开头第二个例子中p+则意味着去打羽毛球,而p-则代表反样例,不去打球(在有关熵的所有计算中我们定义0log0=00log0=0)
即一个分支节点对应的熵公式:

Entropysingle(S)=plog2pEntrop{{y}_{single}}(S)=-plo{{g}_{2}}p

熵是无序性(或不确定性)的度量指标。假如事件A的全概率划分是(A1,A2,…,An),每部分发生的概率是(p1,p2,…,pn),那信息熵定义为:

Entropy(p1,p2,,pn)=p1log2p1pnlog2pn Entropy({{p}_{1}},{{p}_{2}},\cdots ,{{p}_{n}})=-{{p}_{1}}lo{{g}_{2}}{{p}_{1}}-\cdots -{{p}_{n}}lo{{g}_{2}}{{p}_{n}}

通常以2为底数,所以信息熵的单位是bit。
补充两个对数去处公式:
logCAB=logCAlogCBlogAB=logCBlogCA0log20=0 lo{{g}_{C}}\frac{A}{B}=lo{{g}_{C}}A-lo{{g}_{C}}B \\ lo{{g}_{A}}B=\frac{lo{{g}_{C}}B}{lo{{g}_{C}}A} \\ 在有关熵的所有计算中我们定义——0lo{{g}_{2}}0=0
信息熵作为衡量训练样例集合纯度的标准,就是一组数据包含的信息,概率的度量。一组数据越有序信息熵也就越低,极端时如果一组数据中只有一个非0,其它都是0,那么熵等于0,因为只有可能是这个非0的情况发生,它给人们的信息已经确定了,或者说不含有任何信息了,因为信息熵含量为0。一组数据越无序信息熵也就越高,极端时如果一组数据均匀分布,那么它的熵最大,因为我们不知道那种情况发生的概率大些。假如一组数据由{d1,d2,…,dn}构成,其和是sum,那么求信息熵的公式是
H(D)=i=1ndisumlog2disumH(D)=-\sum\limits_{i=1}^{n}{\frac{{{d}_{i}}}{sum}lo{{g}_{2}}\frac{{{d}_{i}}}{sum}}
举例来说,假设S是一个关于布尔概念的有14个样例的集合weather天气数据(在案例中):
它包括9个正例和5个反例(我们采用记号[9+,5-]来概括这样的数据样例),那么S相对于这个布尔样例的熵为:
Entropy([9+5])=914log2914514log2514=0.940Entropy\left( [9+5-] \right)=-\frac{9}{14}lo{{g}_{2}}\frac{9}{14}-\frac{5}{14}lo{{g}_{2}}\frac{5}{14}=0.940
So,根据上述这个公式,我们可以得到:S的所有成员属于同一类,Entropy(S)=0Entropy(S)=0;S的正反样例数量相等,Entropy(S)=1Entropy(S)=1;S的正反样例数量不等,熵介于0,1之间,如下图所示:
树之总结

2.3 信息增益Gain(S,A)——信息度量期望的熵降低

注意:信息增益是gain而不是后面的gini指数
已经有了熵作为衡量训练样例集合纯度的标准,现在可以定义属性分类训练数据的效力的度量标准。这个标准被称为“信息增益(information gain)”。简单的说,一个属性的信息增益就是由于使用这个属性分割样例而导致的期望熵降低(或者说,样本按照某属性划分时造成熵减少的期望)。更精确地讲,一个属性A相对样例集合S的信息增益Gain(S,A)Gain(S,A)被定义为:

Gain(S,A)=Entropy(S)vV(A)SvSEntropy(Sv)V(A)ASSvSAv Gain\left( S,A \right)=Entropy\left( S \right)-\sum\limits_{v\in V\left( A \right)}^{{}}{\frac{\left| {{S}_{v}} \right|}{\left| S \right|}Entropy\left( {{S}_{v}} \right)} \\ V(A) 属性A的值域,S 样本集合,S_v是S在属性A上值等于v的样本集合

【注意】第一个Entropy(S)Entropy(S)是熵定义,第二个则是信息增益Gain(S,A)Gain(S,A)的定义,而Gain(S,A)Gain(S,A)由第一个Entropy(S)Entropy(S)计算出来,记住了。

2.4 信息增益案例

我们统计了14天的气象数据(指标包括outlook,temperature,humidity,windy),并已知这些天气是否打球(play)。

NO. outlook temperature humidity windy play
1 sunny hot high false no
2 sunny hot high true no
3 overcast hot high false yes
4 rainy mild high false yes
5 rainy cool normal false yes
6 rainy cool normal true no
7 overcast cool normal true yes
8 sunny mild high false no
9 sunny cool normal false yes
10 rainy mild normal false yes
11 sunny mild normal true yes
12 overcast mild high true yes
13 overcast hot normal false yes
14 rainy mild high true no

【分析】
共14条记录
目标属性——是否打球,共有2种情况:yes或no
参考属性——outlook(3种取值),temperature(3种取值),humidity(2种取值),windy(2种取值)

outlook temperature humidity windy play
play yes no play yes no play yes no play yes no yes no
sunny 2 3 hot 2 2 high 3 4 false 6 2 9 5
overcast 4 0 mild 4 2 normal 6 1 true 3 3
rainy 3 2 cool 3 1

①先求目标属性的信息熵(yes放在前面)
Entropy(S)=914log2914514log2514=0.940 Entropy\left( S \right)=-\frac{9}{14}lo{{g}_{2}}\frac{9}{14}-\frac{5}{14}lo{{g}_{2}}\frac{5}{14}=0.940
以属性outlook(共14次)为例,有3种取值,分别为sunny(5次)、overcast(4次)和rainy(5次),是否打球次数见上表。sunny共有2+3=5次,则
Entropy(Ssunny)=25log22535log235=0.971 Entropy\left( {{S}_{sunny}} \right)=-\frac{2}{5}lo{{g}_{2}}\frac{2}{5}-\frac{3}{5}lo{{g}_{2}}\frac{3}{5}=0.971\\

Entropy(Ssunny)=25log22535log235=0.971=25(log22log25)35(log23log25)=25(loge2loge2loge5loge2)35(loge3loge2loge5loge2)便 \begin{aligned} Entropy\left( {{S}_{sunny}} \right)&=-\frac{2}{5}lo{{g}_{2}}\frac{2}{5}-\frac{3}{5}lo{{g}_{2}}\frac{3}{5}=0.971\\ &=-\frac{2}{5}\left( lo{{g}_{2}}2-lo{{g}_{2}}5 \right)-\frac{3}{5}\left( lo{{g}_{2}}3-lo{{g}_{2}}5 \right) \\ &=-\frac{2}{5}\left( \frac{lo{{g}_{e}}2}{lo{{g}_{e}}2}-\frac{lo{{g}_{e}}5}{lo{{g}_{e}}2} \right)-\frac{3}{5}\left( \frac{lo{{g}_{e}}3}{lo{{g}_{e}}2}-\frac{lo{{g}_{e}}5}{lo{{g}_{e}}2} \right) \end{aligned} \\ \color{red}{【这里推到是为编程方便】}
其他同理:
Entropy(Sovercast)=44log24404log204=0Entropy(Srainy)=35log23525log225=0.971 Entropy\left( {{S}_{overcast}} \right)=-\frac{4}{4}lo{{g}_{2}}\frac{4}{4}-\frac{0}{4}lo{{g}_{2}}\frac{0}{4}=0 \\ Entropy\left( {{S}_{rainy}} \right)=-\frac{3}{5}lo{{g}_{2}}\frac{3}{5}-\frac{2}{5}lo{{g}_{2}}\frac{2}{5}=0.971
则整个属性outlook(共)的信息熵为上面3个的加权平均值(根据历史统计数据,outlook取值为sunny、overcast、rainy的概率分别是5/14、4/14、5/14):
Entropy(Soutlook)=514Entropy(Ssunny)+414Entropy(Sovercast)+514Entropy(Srainy)=5140.971+4140+5140.971=0.346786+0+0.346786=0.693 \begin{aligned} Entropy\left( {{S}_{outlook}} \right)&=\frac{5}{14}*Entropy\left( {{S}_{sunny}} \right)+\frac{4}{14}*Entropy\left( {{S}_{overcast}} \right)+\frac{5}{14}*Entropy\left( {{S}_{rainy}} \right) \\ &=\frac{5}{14}*0.971+\frac{4}{14}*0+\frac{5}{14}*0.971=\text{0}\text{.346786+0+0}\text{.346786}=0.693 \\ \end{aligned}

③计算【若将outlook作为分裂最佳属性】的信息增益
该概念是指信息熵的有效减少量,该量越高,表明目标属性在该参考属性那失去的信息熵越多,那么该属性越应该在决策树的上层。

Gain(S,outlook)=Entropy(S)Entropy(Soutlook)=0.9400.693=0.247 Gain\left( S,outlook \right)=Entropy(S)-Entropy\left( {{S}_{outlook}} \right)=0.940-0.693=0.247
类似可以求出Gain(S,temperature)=0.029Gain\left( S,temperature \right)=0.029Gain(S,humidity)=0.152Gain\left( S,humidity \right)=0.152Gain(S,windy)=0.048Gain\left( S,windy \right)=0.048
④gain(outlook)最大(即outlook在第一步使系统的信息熵下降得最快),所以决策树的根节点就取outlook。

树之总结
⑤接下来要确定N1取temperature、humidity还是windy?在已知outlook=sunny的情况,根据历史数据,我们作出类似table 2的一张表如下:

outlook temperature humidity windy play
sunny hot high false no
sunny hot high true no
sunny mild high false no
sunny cool normal false yes
sunny mild normal true yes

sunny mild normal true yes
outlook=sunny(共5个样本)对应分析表(称其样本为S2S_2 ):

temperature humidity windy play
play yes no play yes no play yes no yes no
hot 0 2 high 0 3 false 1 2 2 3
mild 1 1 normal 2 0 trur 1 1
cool 1 0

分别计算gain(temperature)、gain(humidity)和gain(windy)【这里只算humidity】:
Gain(S2,humidity)=Entropy(S2)Entropyhumidity(S2)=(25log22535log235)(35×Entropy(Shigh2)+25×Entropy(Snormal2))=0.971(35×(0log2033log233)+25×(22log2220log20))=0.971 \begin{aligned} & Gain\left( {{S}^{2}},humidity \right)=Entropy({{S}^{2}})-Entrop{{y}_{humidity}}\left( {{S}^{2}} \right) \\ & =\left( -\frac{2}{5}lo{{g}_{2}}\frac{2}{5}-\frac{3}{5}lo{{g}_{2}}\frac{3}{5} \right)-\left( \frac{3}{5}\times Entropy\left( S_{high}^{2} \right)+\frac{2}{5}\times Entropy\left( S_{normal}^{2} \right) \right) \\ & =0.971-\left( \frac{3}{5}\times \left( -0lo{{g}_{2}}0-\frac{3}{3}lo{{g}_{2}}\frac{3}{3} \right)+\frac{2}{5}\times \left( -\frac{2}{2}lo{{g}_{2}}\frac{2}{2}-0lo{{g}_{2}}0 \right) \right)=0.971 \\ \end{aligned}
其他2个不进行计算了,通过程序已知道humidity使其Gain变化下降最大,则选其最大者为N1。
【注意】坏情况:如果其他2个计算的Gain系数中有和humidity相同,则就要以一定概率来做出决策.树之总结
依此类推递归,构造决策树。当系统的信息熵降为0时,就没有必要再往下构造决策树了,此时叶子节点都是纯的–这是理想情况。最坏的情况下,决策树的高度为属性(决策变量)的个数,叶子节点不纯(这意味着我们要以一定的概率来作出决策)。最终结果如下:
一些决策树算法使用二分法划分数据,ID3不是这样的。如果依据某个feature划分数据,若该feature可能去4个值,那么该feature下将会有4个分支。每次划分数据集的时候仅仅采用一个feature,也即是信息增益最大的feature。

3 C4.5

上面讨论的决策树的ID3算法,属性只能是枚举型的(离散的),当然属性值可以是连续的数值型,但是需要对这些数据进行预处理,变为离散型的,才可以运用ID3算法。
所以Ross Quinlan又提出了C4.5算法,能够处理属性是连续型的。
C4.5克服了ID3的2个缺点:
①用信息增益选择属性时偏向于选择分枝比较多的属性值,即取值多的属性
②不能处理连贯属性
而且,在C4.5算法中,又提出了两个新的概念:

3.1【分离信息Split Information】

首先,给出分离信息【或称之为分裂信息——分裂信息用来衡量属性分裂数据的广度和均匀】的计算方法,数学符号表达式为:

SplitInformation(S,A)=i=1c(SiSlog2SiS) SplitInformation(S,A)=-\sum\limits_{i=1}^{c}{\left( \frac{\left| {{S}_{i}} \right|}{S}lo{{g}_{2}}\frac{\left| {{S}_{i}} \right|}{S} \right)}

解释为:数据集通过条件属性A的分离信息。上面一个例子,数据集通过Outlook这个条件属性的分离信息,Outlook有三个属性值分别为:Sunny,Overcast,Rain,它们各占5,4,5,所以:

SplitInformation(S,outlook)=514log2514414log2414514log2514 SplitInformation(S,outlook)=-\frac{5}{14}lo{{g}_{2}}\frac{5}{14}-\frac{4}{14}lo{{g}_{2}}\frac{4}{14}-\frac{5}{14}lo{{g}_{2}}\frac{5}{14}

3.2 【信息增益率Information gain ratio】

再次,给出信息增益率的公式:

GainRatio(S,A)=Gain(S,A)SplitInformation(S,A) GainRatio(S,A)=\frac{Gain(S,A)}{SplitInformation(S,A)}

上面这个例子如:数据集S针对Outlook的信息增益率
分子和分母这两个值都已经求出来,选择信息增益率最大的那个属性,作为节点。
【注意】在ID3中用信息增益选择属性时偏向于选择分枝比较多的属性值,即取值多的属性,在C4.5中由于除以了SplitInformation,可以削弱这种作用。

3.3【连续性数据离散化处理】

我们统计了14天的气象数据(指标包括outlook,temperature,humidity,windy),并已知这些天气是否打球(play)。(同上表)
C4.5是如何处理连续属性的呢?实际上它先把连续属性转换为离散属性再进行处理。虽然本质上属性的取值是连续的,但对于有限的采样数据它是离散的,如果有N条样本,那么我们有N-1种离散化(1个1个的尝试)的方法:<=vj的分到左子树,>vj的分到右子树。计算这N-1种情况下最大的信息增益率
在离散属性上只需要计算1次信息增益率,而在连续属性上却需要计算N-1次,计算量是相当大的。有办法可以减少计算量。对于连续属性先进行排序,只有在决策属性发生改变的地方才需要切开。比如对Temperature进行排序
树之总结本来有13种离散化的情况,现在只需计算7种。如果利用增益率来选择连续值属性的分界点,会导致一些副作用。分界点将样本分成两个部分,这两个部分的样本个数之比也会影响增益率。根据增益率公式,我们可以发现,当分界点能够把样本分成数量相等的两个子集时(我们称此时的分界点为等分分界点),增益率的抑制会被最大化,因此等分分界点被过分抑制了。子集样本个数能够影响分界点,显然不合理。因此在决定分界点(如何划分左右子树)是还是采用增益这个指标,而选择属性的时候才使用增益率这个指标。这个改进能够很好得抑制连续值属性的倾向。当然还有其它方法也可以抑制这种倾向,比如MDL。

3.4 剪枝

Tree-Growth终止的条件以及剪枝策略很多,在CART树中已讲了一些。每个叶子上都是“纯的”不见得就是好事,那样会过拟合。还有一个方法是叶子节点上覆盖的样本个数小于一个阈值时停止Tree-Growth。
在《CART树》中介绍了基于代价复杂性的剪枝法,剪枝的目的也是为了避免过拟合。
第一种方法【后剪枝】,也是最简单的方法,称之为基于误判的剪枝。这个思路很直接,完全的决策树不是过度拟合么,我再搞一个测试数据集来纠正它。对于完全决策树中的每一个非叶子节点的子树,我们尝试着把它替换成一个叶子节点,该叶子节点的类别我们用子树所覆盖训练样本中存在最多的那个类来代替,这样就产生了一个简化决策树,然后比较这两个决策树在测试数据集中的表现,如果简化决策树在测试数据集中的错误比较少,并且该子树里面没有包含另外一个具有类似特性的子树(所谓类似的特性,指的就是把子树替换成叶子节点后,其测试数据集误判率降低的特性),那么该子树就可以替换成叶子节点。该算法以bottom-up的方式遍历所有的子树,直至没有任何子树可以替换使得测试数据集的表现得以改进时,算法就可以终止。
第一种方法很直接,但是需要一个额外的测试数据集,能不能不要这个额外的数据集呢?为了解决这个问题,于是就提出了悲观剪枝
悲观剪枝就是递归得估算每个内部节点所覆盖样本节点的误判率。剪枝后该内部节点会变成一个叶子节点,该叶子节点的类别为原内部节点的最优叶子节点所决定。然后比较剪枝前后该节点的错误率来决定是否进行剪枝。该方法和前面提到的第一种方法思路是一致的,不同之处在于如何估计剪枝前分类树内部节点的错误率。
【悲观剪枝】
把一颗子树(具有多个叶子节点)的分类用一个叶子节点来替代的话,在训练集上的误判率肯定是上升的,但是在新数据上不一定。于是我们需要把子树的误判计算加上一个经验性的惩罚因子。对于一颗叶子节点,它覆盖了N个样本,其中有E个错误,那么该叶子节点的错误率为(E+0.5)/N。这个0.5就是惩罚因子.
则一颗子树,它有L个叶子节点,每个叶子节点分别覆盖NiN_i个样本,其中有EiE_i个错误,那么该子树的误判率估计为
e=p=(i=1LEi+0.5L)/i=1LNi e=p={\left( \sum\limits_{i=1}^{L}{{{E}_{i}}}+0.5*L \right)}/{\sum\limits_{i=1}^{L}{{{N}_{i}}}}
这样的话,我们可以看到一颗子树虽然具有多个子节点,但由于加上了惩罚因子,所以子树的误判率计算未必占到便宜。剪枝后内部节点变成了叶子节点,其误判个数J也需要加上一个惩罚因子,变成J+0.5。那么子树是否可以被剪枝就取决于剪枝后的错误**J+0.5*1(剪枝后只有一个叶子节点)**在i=1LEi+0.5L\sum\limits_{i=1}^{L}{{{E}_{i}}}+0.5*L的标准误差内。对于样本的误差率e,我们可以根据经验把它估计成各种各样的分布模型,比如是二项式分布,比如是正态分布。
那么一棵树错误分类一个样本值为1,正确分类一个样本值为0,该树错误分类的概率(误判率)为e(e为分布的固有属性,可以通过e=p=(i=1LEi+0.5L)/i=1LNi  e=p={\left( \sum\limits_{i=1}^{L}{{{E}_{i}}}+0.5*L \right)}/{\sum\limits_{i=1}^{L}{{{N}_{i}}}}\;统计出来),那么树的误判次数就是伯努利分布(就是二项分布)

离散型分布 数学标记 参数 分布律或概率密度 数学期望 方差
单点分布(退化分布) b0(a,1){{b}_{0}}(a,1) aa P(X=a)=1P(X=a)=1 aa 00
(0-1)分布(两点分布或伯努利分布) b(1,p)b(1,p) 0<p<10<p<1 P{X=k}=pk(1p)1kk=0,1\begin{aligned} P\left\{ X=k \right\} =&{{p}^{k}}{{\left( 1-p \right)}^{1-k}} \\ & k=0,1 \\ \end{aligned} pp 1p1-p
二项分布 B(n,p)B\left( n,p \right) 0<p<1n1\begin{aligned} 0<p<1 \\ n\ge 1 \\ \end{aligned} P{X=k}=Cnkpk(1p)nkk=0,1,2\begin{aligned}\\ P\left\{ X=k \right\}&=C_{n}^{k}{{p}^{k}}{{\left( 1-p \right)}^{n-k}} \\ & k=0,1,2\cdots\\\end{aligned} npnp np(1p)np(1-p)

我们可以估计出该树的误判次数均值和标准差:
E(subtree_count)=Nevar(subtree_err_count)=Ne(1e) E\left( subtree\_count \right)=N*e \\ var(subtree\_err\_count)=\sqrt{N*e*\left( 1-e \right)}
把子树替换成叶子节点后,该叶子的误判次数也是一个伯努利分布,其概率误判率e为(E+0.5)/N,因此叶子节点的误判次数均值为
E(leaf_err_count)=NeE\left( leaf\_err\_count \right)=N*e

使用训练数据,子树总是比替换为一个叶节点后产生的误差小,但是使用校正后有误差计算方法却并非如此,当子树的误判个数大过对应叶节点的误判个数一个标准差之后,就决定剪枝:
E(subtree_count)var(subtree_err_count)>E(leaf_err_count)E\left( subtree\_count \right)-var(subtree\_err\_count)>E\left( leaf\_err\_count \right)
这个条件就是剪枝的标准。
当并不一定非要大一个标准差,可以给定任意的置信区间,我们设定一定的显著性因子,就可以估算出误判次数的上下界。

3.5【悲观后剪枝案例】

树之总结
【剪枝规则】
它替换成一个叶子节点,该叶子节点的类别我们用子树所覆盖训练样本中存在最多的那个类来代替
【T4子树解释】
T4共覆盖16个样本,其3个叶子节点,T8覆盖3+2=5个样本,T9覆盖0+2=2个样本,T7覆盖6+3个样本【对于T6,它将3+4个样本分别划分给T8和T9】,划分左右子树。
【剪枝前——3个叶子节点 T7 T8 T9】
T4: 9+7——9表示有9个样本属于第1类,7表示有7个样本属于第2类【左边表示第一类,右边反之】
T7: 6+3——6表示在T4的属于第1类的9个样本中的6个样本正确划分为了类1(叶子节点有结果)
      3表示在T4的属于第2类的7个样本中的3个样本错误划分为了类1——误判3个
T6: 3+4——正确情况下应该是3个样本属于第1类,4个样本属于第2类
T8: 3+2——3表示在T6的属于第1类的3个样本中的3个样本正确划分为了类1(叶子节点有结果)
      2表示在T6的属于第2类的4个样本中的2个样本错误划分为了类1——误判2个
T9: 0+2——0表示在T6的属于第1类的3个样本中的0个样本没被划分(没有样本了)
      2表示在T6的属于第2类的4个样本中的2个样本正确划分为了类2
则综上,3个叶子节点时,误判共有3+2=5个,即T4这棵子树的误差率:
e=p=(3+2)+0.5316=0.40625e=p=\frac{(3+2)+0.5*3}{16}=0.40625
子树误差率的标准误差:
E(subtree_count)=Ne=16×0.40625=6.5var(subtree_err_count)=Ne(1e)=16×0.40625×(10.40625)=1.96E\left( subtree\_count \right)=N*e=16\times 0.40625=6.5\\ var(subtree\_err\_count)=\sqrt{N*e*(1-e)}=\sqrt{16\times 0.40625\times \left( 1-0.40625 \right)}=1.96
【剪枝后——1个叶子节点 T4 归属于类1】
子树替换为一个叶节点后,其误差率为:
e=p=7+0.5116=0.46875E(leaf_count)=Ne=16×0.46875=7.5e=p=\frac{7+0.5*1}{16}=0.46875\\ E\left( leaf\_count \right)=N*e=16\times 0.46875=7.5
因为 6.5+1.96>7.56.5+1.96>7.5,所以决定将子树T4替换这一个叶子节点。这个案例最后是有问题的,应该是6.5-1.96是否大于7.5,所以举例不恰当

4 C5.0

这是决策树C4.5的商用算法,在内存管理等方面,给出了改进。比如在商用软件SPSS中,就有该算法。
注意上述ID3\C4.5\C5.0三个算法只能做分类,不能做回归,下一篇博文CART类似于C4.5,但可以做回归。
开源的软件:
java语言中最著名的的Weka,对ID3,C4.5都有实现。

5 CART

注意上述ID3、C4.5和C5.0三个算法只能做分类,不能做回归,下一篇博文CART类似于C4.5,但可以做回归。
分类回归树算法:CART(Classification And Regression Tree)算法采用一种二分递归分割的技术,将当前的样本集分为两个子样本集,使得生成的的每个非叶子节点都有两个分支。因此,CART算法生成的决策树是结构简洁的二叉树。
分类树两个基本思想:
第1个是将训练样本进行递归地划分自变量空间进行建树的想法
第2个想法是用验证数据进行剪枝。

建树:在分类回归树中,我们把类别集Result表示因变量,选取的属性集attributelist表示自变量,通过递归的方式把attributelist把p维空间划分为不重叠的矩形,具体建树的基本步骤

CART (DataSet, featureList): ——DataSet为样本数据集, featureList为特征列表
创建根节点R
RR分配类别
if RR 都属于同一类别 or RR中只剩下1个样本则返回RR为叶节点,为其分配属性
递归情况:
for each featureList 中属性执行该属性上的一个划分,计算此划分的GINI指数
  R的测试属性test_feature= featureList中最小GINI指数的属性
  划分DataSet得到T1和T2子集
  对于T1T1重复CART (T1_DataSet, T1_featureList)
  对于T2T2重复CART (T2_DataSet, T2_featureList)
生成树之后使用后剪枝
  在树的生成过程中,多展开一层就会有多一些的信息被发现,CART算法运行到不能再长出分支为止,从而得到一棵最大的决策树。然后对这棵大树进行剪枝。

5.1 【GINI——基尼系数】

CART算法是怎样进行样本划分的呢?它检查每个变量和该变量所有可能的划分值来发现最好的划分:
对离散值x,y,x{x,y,x},则在该属性上的划分有三种情况(x,y,z,x,z,y,y,z,x)({{x,y},{z}},{{x,z},y},{{y,z},x}),空集和全集的划分除外;
对于连续值处理引进“分裂点”的思想,假设样本集中某个属性共nn个连续值,则有n1n-1个分裂点,每个“分裂点”为相邻两个连续值的均值(a[i]+a[i+1])/2(a[i]+a[i+1])/2
将每个属性的所有划分按照他们能减少的杂质(合成物中的异质,不同成分)量来进行排序,杂质的减少被定义为划分前的杂质减去划分之后每个节点的杂质量*划分所占样本比率之和。
目前最流行的杂质度量方法是:GINI指标,如果我们用k,k=1,2,3Ck=1,2,3……C表示类,其中C是类别集Result的因变量数目,一个节点A的GINI不纯度定义为:

GINI(A)=1k=1Cpk2杂质的计算公式——GINI(A)=1-\sum\limits_{k=1}^{C}{p_{k}^{2}}

其中,PkP_k表示观测点中属于kk类得概率,当Gini(A)=0Gini(A)=0时所有样本属于同一类,当所有类在节点中以相同的概率出现时,Gini(A)Gini(A)最大化,此时值为(C1)C/2(C-1)C/2
对于分类回归树,A如果它不满足“T都属于同一类别or T中只剩下一个样本”,则此节点为非叶节点,所以尝试根据样本的每一个属性及可能的属性值,对样本的进行二元划分,假设分类后A分为B和C,其中B占A中样本的比例为pp,C为qq(显然pqp+q=1)。

Gini(A)pGini(B)qGini(C)杂质的改变量的计算公式——Gini(A) -p*Gini(B)-q*Gini(C)

每次划分该值应为非负,只有这样划分才有意义,对每个属性值尝试划分的目的就是找到杂质改变量最大的一个划分,该属性值划分子树即为最优分支。

5.2【GINI案例1】

对于以下生物分类数据:

NO. 名称 体温 表皮覆盖 胎生 产蛋 能飞 水生 有腿 冬眠 类标记
1 恒温 毛发 哺乳类
2 巨蟒 冷血 鳞片 爬行类
3 鲑鱼 冷血 鳞片 鱼类
4 恒温 毛发 哺乳类
5 冷血 有时 两栖类
6 巨蜥 冷血 鳞片 爬行类
7 蝙蝠 恒温 毛发 哺乳类
8 鸽子 恒温 羽毛 鸟类
9 恒温 哺乳类
10 豹纹鲨 冷血 鳞片 鱼类
11 海龟 冷血 鳞片 有时 爬行类
12 企鹅 恒温 羽毛 有时 鸟类
13 豪猪 恒温 刚毛 哺乳类
14 冷血 鳞片 鱼类
15 蝾螈 冷血 有时 两栖类

上例是属性有8个,每个属性又有多少离散的值可取。在决策树的每一个节点上我们可以按任一个属性的任一个值进行划分。比如最开始我们按:
1)表面覆盖为毛发和非毛发
2)表面覆盖为鳞片和非鳞片
3)体温为恒温和非恒温
等等产生当前节点的左右两个孩子。按哪种划分最好呢?有3个标准可以用来衡量划分的好坏:GINI指数、双化指数、有序双化指数。下面我们只讲GINI指数。
【分析】
共15条记录
目标属性——生物分类,共有5种情况:哺乳类、爬行类、鱼类、两栖类、鸟类
参考属性——8种
总体内包含的类别越杂乱,GINI指数就越大(跟熵的概念很相似)。分析表格如下:

体温 哺乳类 爬行类 鱼类 鸟类 两栖类
体温 哺乳类 爬行类 鱼类 鸟类 两栖类
恒温 5 0 0 2 0
非恒温 0 3 3 0 2

体温为恒温时包含哺乳类5个、鸟类2个,则:
GINI(=)=1[(57)2+(27)2]=2049GINI(=)=1-\left[ {{\left( \frac{5}{7} \right)}^{2}}+{{\left( \frac{2}{7} \right)}^{2}} \right]=\frac{20}{49}
体温为非恒温时包含爬行类3个、鱼类3个、两栖类2个,则:
GINI(=)=1[(38)2+(38)2+(28)2]=4264GINI(=)=1-\left[ {{\left( \frac{3}{8} \right)}^{2}}+{{\left( \frac{3}{8} \right)}^{2}}+{{\left( \frac{2}{8} \right)}^{2}} \right]=\frac{42}{64}
故若按照“体温为恒温(7样本)和非恒温(8样本)”进行划分的话,我们得到GINI的增益(类比信息增益):
GINI()=715×2049+815×4264GINI()=\frac{7}{15}\times \frac{20}{49}+\frac{8}{15}\times \frac{42}{64}
最好的划分就是使得GINI最小的划分。

5.3【GINI案例2】

还是以决策树之ID3中的例子,当然CART是可以处理条件属性是连续值的分类问题。CART是一个二叉树,我们统计了14天的气象数据(指标包括outlook,temperature,humidity,windy),并已知这些天气是否打球(play)。
【分析】
共14条记录
目标属性——是否打球,共有2种情况:yes或no
参考属性——outlook(3种取值),temperature(连续属性),humidity(连续属性),windy(2种取值)

outlook temperature humidity windy play
play yes no play yes no play yes no play yes no yes no
sunny 2 3 false 6 2 9 5
overcast 4 0 true 3 3
rainy 3 2

【目标属性的Gini值】
targetGini=1[(914)2+(514)2]=0.4592targetGini=1-\left[ {{\left( \frac{9}{14} \right)}^{2}}+{{\left( \frac{5}{14} \right)}^{2}} \right]=0.4592
我们先根据Outlook条件属性计算GINI,Outlook有三个属性值,因为CART是一个二叉树,我们把三个属性值按照2+1的组合**(有三种)**即:
【outlook第1种划分】

play sunny and overcast rainy
yes 6 3
no 3 2

针对上表:
Gini(sunnyovercast)=1[(69)2+(39)2]=0.4444Gini(rain)=1[(35)2+(25)2]=0.4800Gini=914×0.4444+514×0.4800=0.4571differGini=targetGiniGini=0.45920.4571=0.0021Gini\left( sunny\bigcup overcast \right)=1-\left[ {{\left( \frac{6}{9} \right)}^{2}}+{{\left( \frac{3}{9} \right)}^{2}} \right]=0.4444\\ Gini\left( rain \right)=1-\left[ {{\left( \frac{3}{5} \right)}^{2}}+{{\left( \frac{2}{5} \right)}^{2}} \right]=0.4800\\ Gini=\frac{9}{14}\times 0.4444+\frac{5}{14}\times \text{0}\text{.4800}=0.4571\\ differGini=targetGini-Gini=0.4592-0.4571=0.0021
【outlook第2种划分】

play sunny and rainy overcast
yes 5 4
no 5 0

针对上表:
Gini(sunnyrain)=1[(510)2+(510)2]=0.5Gini(overcast)=1[(44)2+(04)2]=0Gini=1014×0.5+414×0.0=514=0.3571differGini=targetGiniGini=0.45920.3571=0.1021 Gini\left( sunny\bigcup rain \right)=1-\left[ {{\left( \frac{5}{10} \right)}^{2}}+{{\left( \frac{5}{10} \right)}^{2}} \right]=0.5\\ Gini\left( overcast \right)=1-\left[ {{\left( \frac{4}{4} \right)}^{2}}+{{\left( \frac{0}{4} \right)}^{2}} \right]=0\\ Gini=\frac{10}{14}\times 0.5+\frac{4}{14}\times 0.0=\frac{5}{14}=0.3571\\ differGini=targetGini-Gini=0.4592-0.3571=0.1021
然后根据其他条件属性,继续计算GINI,然后选择最小的那一个GINI,作为分裂节点。
【注意】根据GINI最小原则,其实ID3中的信息增益不需要进行求,直接求分裂后的信息(熵最小即可),也就是说让分裂后的熵最小即可(节省计算)。

5.4【代价复杂性剪枝(后剪枝)】

当分类回归树划分得太细时,会对噪声数据产生过拟合作用。因此我们要通过剪枝来解决。剪枝又分为前剪枝和后剪枝:前剪枝是指在构造树的过程中就知道哪些节点可以剪掉,于是干脆不对这些节点进行分裂,在N皇后问题和背包问题中用的都是前剪枝,上面的χ2方法也可以认为是一种前剪枝;后剪枝是指构造出完整的决策树之后再来考查哪些子树可以剪掉。
在分类回归树中可以使用的后剪枝方法有多种,比如:代价复杂性剪枝、最小误差剪枝、悲观误差剪枝等等。这里我们只介绍代价复杂性剪枝法。
对于分类回归树中的每一个非叶子节点计算它的表面误差率增益值αα
α=R(t)R(Tt)NTt1R(t)=r(t)p(t)α=\frac{R(t)-R(T_t)}{|N_{T_t}|-1}\\ R(t)=r(t) * p(t)
NTtN_{T_t} 子树中包含的叶子节点个数
R(t)R(t)是节点tt的误差代价,如果该节点被剪枝
r(t)r(t)是节点tt的误差率;
p(t)p(t)是节点tt上的数据占所有数据的比例。
R(Tt)R(T_t)是子树TtT_t的误差代价,如果该节点不被剪枝。它等于子树TtT_t上所有叶子节点的误差代价之和。
比如有个非叶子节点t4t_4如图所示
树之总结
已知所有的数据总共有60条,则节点KaTeX parse error: Expected group after '_' at position 3: t4_̲的节点误差代价为:
R(Ti)=r(t)p(t)=7161660)=760R(T_i)=r(t) * p(t)=\frac{7}{16} * \frac{16}{60}) =\frac{7}{60}
子树误差代价为:
R(Ti)=R(i)=(25560)+(02260)+(39960)=560R(T_i)=\sum{R(i)}=(\frac{2}{5} * \frac{5}{60}) + (\frac{0}{2} * \frac{2}{60}) + (\frac{3}{9} * \frac{9}{60}) = \frac{5}{60}
t4t_4为根节点的子树上叶子节点有3个,最终:
α=1/605/6031=16α=\frac{1/60-5/60}{3-1}=\frac{1}{6}
找到αα值最小的非叶子节点,令其左右孩子为NULL。当多个非叶子节点的αα值同时达到最小时,取NTtN_{T_t}最大的进行剪枝。

5.5 Classification描述

CART_classification(DataSet, featureList, alpha): ——DataSet为样本数据集, featureList为特征列表
创建根节点R
若当前DataSet中的数据的类别相同,则标记R的类别为该类
若决策树高度大于alpha,则不再分解,标记R的类别classify(DataSet)
递归情况:
标记R的类别classify(DataSet)
   从featureList中选择属性F(选择GINI(DataSet,F)最小的属性划分,连续属性参考C4.5的离散化过程以Gini最小作为划分标准)
   根据F,将DataSet做二元划分DS_L和DS_R:
     若DS_L或DS_R为空,则不再分解
     若DS_L和DS_R都不为空,节点
    C_L=CART_classification(DS_L, featureList, alpha);
    C_R=CART_classification(DS_R featureList, alpha);
    将节点C_L和C_R添加为R的左右子节点

【注意】GINI(DataSet,F)指基尼系数

5.5 Regression描述

CART_regression(DataSet, featureList, alpha, beta): ——DataSet为样本数据集, featureList为特征列表
创建根节点R
若当前DataSet中的数据的类别相同,则标记R的类别为该类
若决策树高度大于alpha,则不再分解,标记R的类别classify(DataSet)
递归情况:
标记R的类别classify(DataSet)
   从featureList中选择属性F(选择phi(DataSet,F)最大的属性划分,连续属性参考C4.5的离散化过程以Gini最小作为划分标准)
   根据F,将DataSet做二元划分DS_L和DS_R:
     若DS_L或DS_R为空,则不再分解
     若DS_L和DS_R都不为空,节点
    C_L=CART_regression(DS_L, featureList, alpha, beta);
    C_R=CART_regression(DS_R featureList, alpha, beta);
    将节点C_L和C_R添加为R的左右子节点

【注意】GINI(DataSet,F)指基尼系数
分类树与回归树的差别在于空间划分方法一个是线性一个是非线性
【注意】phi(DataSet,F) 指 回归均方差 最大

6 RandomForest

6.1 基本原理

建立随机森林的基本思想是, 通过自助法(boot-strap)重采样技术, 不断生成训练样本和测试样本, 由训练样本生成多个分类树组成随机森林, 测试数据的分类结果按分类树投票多少形成的分数而定。
随机森林有两个重要参数:
一是树节点预选的变量个数F=mtryF=mtry
二随机森林中树的个数ntreentree , 一般设定:
F=mtry=mallmallntree=500F=mtry\text{=}\sqrt{mall}\\ mall为所有变量的个数,假设树的个数ntree=500

常见的集成学习算法有装袋算法、提升算法以及随机森林三种方法。ID3 CART C4.5
随机森林方法与前两者相似之处在于,它们都会对样本进行有放回抽样和集成预测,但区别在于随机森林还对解释变量(自变量)进行了随机抽样。随机森林不需要对树模型进行剪枝,而是生成多个完整深度的树模型。在回归问题中,将多个树模型的预测值进行求平均值,以计算最终预测值。对于分类问题,则通过多数投票方式来产生最终预测
随机森林计算步骤:(随机森林方法对数据的量纲和单位并不敏感,并不需进行标准化或归一化处理)
假设我们有N个样本,M个特征:OOB
(1)从原始训练样本中采用Bootstrap抽样随机抽出k个样本,k<Nk<N
(2)从解释变量(自变量)中随机抽出m个特征,从抽中变量中选择最能有效分割数据的变量,使分割后的子集内部变异性最小。对于连续数据通常是采用均方误作为判断指标,对于离散数据则多采用基尼值
(3)依据步骤二得到的变量将数据分割为两个纯度较高的子集。
(4)对子集重复步骤三直到分割停止。这就完成了单棵树的建模。
(5)重复步骤(1)到步骤(4)XX次,就构建了有XX棵树的随机森林模型。

具体算法可抽象为:

(1)进行NN次的bootstrap抽样,即每次从TT中有放回的随机抽取nn个样本,形成新的训练集Tk{{T}_{k}},则
当次未被选中的样本称为OOBOOB数据(outofbagout-of-bag),TTTk{{T}_{k}}OOBkOO{{B}_{k}}三者满足这样的关系。T=TkOOBkT={{T}_{k}}\bigcup OO{{B}_{k}}
(2)用Tk{{T}_{k}}建立如下的分类树treektre{{e}_{k}}:在进行节点选择变量时,并非从所有的变量中选取最好的一个变量
进行分裂,而是每次从所有变量中随机选择m(mp)m(m\le p)个变量,再从mm个变量中选择最佳的变量进行分裂。在整个建立随机森林的过程中,mm值保持不变。当m=pm=p时,就是所谓的baggingbagging
(3)对己建立的随机森林进行预测:用treektre{{e}_{k}}、预测OOBkOO{{B}_{k}},进行NN次,每次记录OOBkOO{{B}_{k}}的分类结果。
对第ii个样本进行如下的投票方式,找出含有第ii个样本的OOBkOO{{B}_{k}}、对应treektre{{e}_{k}}的预测结果进行统计,投票最多的类,即为该样本的预测结果,此过程也称为OOBkOO{{B}_{k}}估计。

6.2 变量重要性计算

随机森林的一个重要特点是估计变量的重要性程度。可以简单的表述为,当某个变量的OOBOOB被重新随机打乱或加入噪声后,其预测的错分类增加的幅度越大,该变量越重要。具体过程可表述为:
(1)用己建立的随机森林进行预测,得到OOBOOB误分率RR (2)度量第ii个变量的重要性:
随机打乱OOB1,OOB2,,OOBNOO{{B}_{1}},OO{{B}_{2}},\cdots ,OO{{B}_{N}}中第ii个变量对应的样本值(或者加入噪声),用己建立的模型重新预测,得到一个新的OOB误分率Ri{{R}_{i}}
(3)用Ri{{R}_{i}}与R之差ΔRi\Delta {{R}_{i}}作为第ii个变量重要性度量值,若ΔRi\Delta {{R}_{i}}越大,则表示该变量越重要。 标准化后可得到每个变量的重要性βi{{\beta }_{i}}: βi=RiRi=1pRiR{{\beta }_{i}}\text{=}\frac{\left| {{R}_{i}}-R \right|}{\sum\limits_{i=1}^{p}{\left| {{R}_{i}}-R \right|}}

Reference

【文章如有侵权、未引用出处、有更好资料等请及时联系126邮箱名whaozl(即微信名) 或 留言评论】

相关文章:

  • 2022-12-23
  • 2021-11-19
  • 2021-10-15
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-07
  • 2022-12-23
  • 2021-07-18
  • 2021-09-06
  • 2022-12-23
  • 2021-12-10
  • 2021-12-29
相关资源
相似解决方案