前言
决策树是一类常见的机器学习方法,属于监督学习算法。决策树本身不是一种很复杂的算法,只需要简单的数学基础的就可以理解其内容。一些比较典型的决策树算法有: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
中第
从信息论中我们知道熵的定义时“用来消除不确定性的东西”。换句话说,就是对不确定性的度量。熵越大,不确定性越大;熵越小,不确定性越小,这也是通常我们希望看到的。所以,我们希望 Ent(D) 尽可能地小。
信息增益(information gain)
假定离散属性
a
有
根据前面的公式,可以很容易计算出
Dv
的信息熵
Ent(D)
。
根据属性划分后,样本数据集
D
被分到了各个子集中,那么理所当然,熵也会发生变化。现在想要求出划分之后的熵,跟划分前的熵作差就可以知道熵的变化值。这个熵的差值就意味着不确定性的减少,而我们希望这个差值能尽可能大。这个差值我们就叫做信息增益。
这里,划分后的结点所包含的样本数不同,所以对其每个结点的熵做了加权平均。每个结点的权重是 |Dv||D| ,即样本数越多的结点影响越大。
一般来说,在选择划分属性时,我们希望减少不确定性,那么信息增益要尽可能大。所以在划分时,会计算每个属性的信息增益,并选取最大值。
著名的ID3算法就是基于信息增益来选择划分属性的。
增益率(Gain Ratio)
增益率定义为:
其中,
称为属性 a 的固有值。其特点是:属性
前面提到的信息增益 Gain(D,a) 会对可取值数目多( V 更大)的属性有所偏好,而为了消除这个偏好的影响,所以引入了
在C4.5算法中使用的就是增益率,但是并不是直接使用增益率作为划分标准。而是,先从候选划分属性中通过信息增益划分出高于平均水平的属性,随后,再选取增益率最高的那个属性。
基尼指数(Gini index)
CART决策树算法中采用的就是基尼指数。
直观地理解,相当于在数据集D中抽取两个样本(总共有 |γ| 个类,默认取第 k 个类),这两个样本的类别不一样的概率。也等于两个类都相同的概率的反例,即1减去它。
对于属性 a 的基尼指数:
选取是的划分后基尼指数最小的属性作为最优划分属性:
剪枝处理
预剪枝(prepruning)
在决策树生成过程中,对每个结点在划分前进行估计。若当前结点划分后不能使决策树的泛化性能有所提高(一般来说是,在交叉训练集中表现得更好),则停止划分并把当前结点标记为叶节点,类别就去出现次数最多的那个类别。
后剪枝
从训练集中生成好了一个完整的决策树之后,然后自底向上对非叶结点进行测试。若将该节点对应的子树换成叶节点,能带来决策树泛化性能的提升(划分前后的准确率提高),则将该指数替换为结点。
连续值处理
决策树的属性并不只有离散值,也可能出现属性是一个连续值的情况。由于连续属性的可取值数目不再是有限的,所以不能再根据连续属性的可取值来划分结点。
C4.5决策树算法中:采用二分法(bi-partition)对连续值进行处理。
给定样本集
D
和连续属性值
对于连续属性
a
,我么你可以考察包含
选取区间 [ai,ai+1) 的中点作为候选划分点。
其中, Gain(D,a,t) 是样本集 D 基于划分点
之后的处理方法与普通的离散值的处理方法一样。
缺失值处理
有时会遇到不完整的样本,即样本的某些属性值有缺失。但是有时,这些属性值虽然缺失了一部分,但却对训练结果有好的影响。所以不能简单地就丢弃掉这些数据。
给定训练集
D
和属性
假定属性
a
有
显然有:
假定为每一个样本 x 都赋予一个权重
直观地看,对于属性 a :
pk˜ 表示无缺失值样本中第 k 类所占的比例;
则可以将信息增益的计算公式推广为:
其中,
决策树算法的原理不算特别复杂,主要还是在编程。下次再去整理下程序。
(ง •̀_•́)ง