您的位置:首页 > 其它

机器学习入门学习笔记:(3.1)决策树算法

2017-10-30 20:08 651 查看

前言

  决策树是一类常见的机器学习方法,属于监督学习算法。决策树本身不是一种很复杂的算法,只需要简单的数学基础的就可以理解其内容。一些比较典型的决策树算法有:ID3、C4.5、CART等等决策树算法。

理论介绍

  一般的,一棵决策树包含一个根结点、若干个内部结点、若干个叶结点。叶结点是最后的决策结果,其余结点都对应与某一个属性的测试(决策)。每个结点所包含的样本集合根据对属性的决策,往下划分到其的子结点中。根节点包含整个样本集,随着树的结点逐渐往下延伸,样本集也被分散到各个结点中。

算法伪代码:

算法:

Generate_decision_tree(D, A)。由给定的训练数据产生一棵判定树。

输入:

训练集 D={(x1,y1),(x2,y2),...,(xm,ym)}

属性集 A={a1,a2,...,ad}

输出:

返回的是一个决策树。

方法:

Generate_decision_tree(D, A)

创建结点 N;

if D都在同一个类C then //类标号属性的值均为C,其候选属性值不考虑

  return N 作为叶结点,以类C标记;

if A为空集 or D中样本在A上取值相同 then

  return N 作为叶结点,标记为D中出现最多的类;

选择A中具有最高信息增益的属性a∗;//找出最好的划分属性

for 遍历a∗中的所有可能取值av∗ //将样本D按照属性a∗进行划分

  由结点 N 长出一个分枝;

  令Dv表示样本集D中在该属性a∗上取值为av∗的样本子集

  if Dv为空 then

    加上一个叶节点,标记为样本集D中出现最多的类;//从样本中找出类标号数量最多的,作为此节点的标记

  else

    加上一个由 Generate_decision_tree(Dv , A–a∗)返回的结点;//对数据子集Dv递归调用,此时候选属性已,因为已经用作结点,所以属性A要删除a∗

参考博客:http://blog.csdn.net/liema2000/article/details/6118384

  从伪代码中我们可以看出:决策树的生成是一个不断向下调用递归函数的过程。那么我们就希望关注递归函数的返回条件,也就是决策树生成到了叶结点的时候。从伪代码中可以发现有以下几种情况:

当前结点包含的所有样本都是属于同一个类别,这时没有必要划分了

当前属性集为空时,也就是没有属性可以用来划分了

当前属性下,所有样本取值一样,即当前属性无法对数据集划分起到作用

当前属性下所含的样本集合为空,即没有多的样本来划分了

  以上对应伪代码中的几个if判断,如果符合条件,则将当前结点视作叶节点,并返回。

划分依据

信息熵(information entropy)

  假定当前样本集合D中第k类样本所占的比例为pk(k=1,2,3,...,|γ|),则D的信息熵定义为:

Ent(D)=−∑k=1|γ|pklog2pk

  从信息论中我们知道熵的定义时“用来消除不确定性的东西”。换句话说,就是对不确定性的度量。熵越大,不确定性越大;熵越小,不确定性越小,这也是通常我们希望看到的。所以,我们希望Ent(D)尽可能地小。

信息增益(information gain)

  假定离散属性a有V个可能的取值{a1,a2,a3,...,aV},若使用属性a对样本集合D进行划分,则会产生V个分支结点。那么其中第v个结点,包含了样本集合D在属性a上取值为av的样本子集,记为Dv。

  根据前面的公式,可以很容易计算出Dv的信息熵Ent(D)。

  根据属性划分后,样本数据集D被分到了各个子集中,那么理所当然,熵也会发生变化。现在想要求出划分之后的熵,跟划分前的熵作差就可以知道熵的变化值。这个熵的差值就意味着不确定性的减少,而我们希望这个差值能尽可能大。这个差值我们就叫做信息增益

Gain(D,a)=Ent(D)−∑v=1V|Dv||D|Ent(Dv)

  这里,划分后的结点所包含的样本数不同,所以对其每个结点的熵做了加权平均。每个结点的权重是|Dv||D|,即样本数越多的结点影响越大。

  一般来说,在选择划分属性时,我们希望减少不确定性,那么信息增益要尽可能大。所以在划分时,会计算每个属性的信息增益,并选取最大值。

a∗=arga∈Amax(Gain(D,a))

  著名的ID3算法就是基于信息增益来选择划分属性的。

增益率(Gain Ratio)

  增益率定义为:

Gainratio(D,a)=Gain(D,a)IV(a)

  其中,

IV(a)=−∑v=1V|Dv||D|log2|Dv||D|

  称为属性a的固有值。其特点是:属性a的可能取值属性越多,即V越大,则IV(a)的值就会越大。

  前面提到的信息增益Gain(D,a)会对可取值数目多(V更大)的属性有所偏好,而为了消除这个偏好的影响,所以引入了IV(a)。与信息增益相反,增益率会对可取值数目较少的属性有所偏好。

  在C4.5算法中使用的就是增益率,但是并不是直接使用增益率作为划分标准。而是,先从候选划分属性中通过信息增益划分出高于平均水平的属性,随后,再选取增益率最高的那个属性。

基尼指数(Gini index)

  CART决策树算法中采用的就是基尼指数。

Gini(D)=∑k=1|γ|∑k′≠kpkpk′=1−∑k=1|γ|p2k

  直观地理解,相当于在数据集D中抽取两个样本(总共有|γ|个类,默认取第k个类),这两个样本的类别不一样的概率。也等于两个类都相同的概率的反例,即1减去它。Gini(D)越小越好。

  对于属性a的基尼指数:

Giniindex(D,a)=∑v=1V|Dv||D|Gini(Dv)

  选取是的划分后基尼指数最小的属性作为最优划分属性:

a∗=arga∈Amax(Giniindex(D,a))

剪枝处理

预剪枝(prepruning)

  在决策树生成过程中,对每个结点在划分前进行估计。若当前结点划分后不能使决策树的泛化性能有所提高(一般来说是,在交叉训练集中表现得更好),则停止划分并把当前结点标记为叶节点,类别就去出现次数最多的那个类别。

后剪枝

  从训练集中生成好了一个完整的决策树之后,然后自底向上对非叶结点进行测试。若将该节点对应的子树换成叶节点,能带来决策树泛化性能的提升(划分前后的准确率提高),则将该指数替换为结点。

连续值处理

  决策树的属性并不只有离散值,也可能出现属性是一个连续值的情况。由于连续属性的可取值数目不再是有限的,所以不能再根据连续属性的可取值来划分结点。

  C4.5决策树算法中:采用二分法(bi-partition)对连续值进行处理。

  给定样本集D和连续属性值a,假定属性a在数据集D上出现了n个可能的取值,将这些值从小到大排序,即为{a1,a2,a3,...,an}。基于划分点t可以将D划分为子集D−t和D+t,其中D−t包含了那些在属性a上取值不大于t的样本,而D+t则包含了那些在属性a上取值大于t的样本。

  对于连续属性a,我么你可以考察包含n−1个元素的候选划分点集合:

Ta={ai+ai+12|1≤i≤n−1}

  选取区间[ai,ai+1)的中点作为候选划分点。

Gain(D,a)=maxt∈TaGain(D,a,t)=maxt∈TaEnt(D)−∑λ∈(−,+)∣∣Dtt∣∣|D|Ent(Dλt)

  其中,Gain(D,a,t)是样本集D基于划分点t二分后的信息增益。

  之后的处理方法与普通的离散值的处理方法一样。

缺失值处理

  有时会遇到不完整的样本,即样本的某些属性值有缺失。但是有时,这些属性值虽然缺失了一部分,但却对训练结果有好的影响。所以不能简单地就丢弃掉这些数据。

  给定训练集D和属性a,令D˜表示D在属性a上没有缺失值的样本子集。

  假定属性a有V个可取值{a1,a2,...,an},令Dv˜表示D˜中在属性a上取值为av的样本子集,Dk˜表示D˜中属于第k类(k=1,2,3...,|γ|)的样本子集。

  显然有:D˜=⋃k=1|γ|Dk˜D˜=⋃v=1VDv˜

  假定为每一个样本x都赋予一个权重ωx,有:

ρ=∑x∈D˜ωx∑x∈Dωxpk˜=∑x∈Dk˜ωx∑x∈Dωx,(1≤k≤|γ|)rv˜=∑x∈Dv˜ωx∑x∈Dωx,(1≤v≤V)

  直观地看,对于属性a:

  ρ表示无缺失值样本所占的比例;

  pk˜表示无缺失值样本中第k类所占的比例;

  rv˜表示无缺失值样本中在属性a上取值av的样本所占的比例。

  则可以将信息增益的计算公式推广为:

Gain(D,a)=ρ×Gain(D,a)=ρ×(Ent(D˜)−∑v=1Vrv˜Ent(Dv˜))

  其中,

Ent(D˜)=−∑k=1|γ|pk˜log2pk˜

  决策树算法的原理不算特别复杂,主要还是在编程。下次再去整理下程序。

  (ง •̀_•́)ง
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐