决策树是一类常见的机器学习方法,属于监督学习算法。决策树本身不是一种很复杂的算法,只需要简单的数学基础的就可以理解其内容。一些比较典型的决策树算法有: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判断,如果符合条件,则将当前结点视作叶节点,并返回。
假定当前样本集合 D 中第 k 类样本所占的比例为 pk(k=1,2,3,...,|γ|) ,则 D 的信息熵定义为:
假定离散属性 a 有 V 个可能的取值 {a1,a2,a3,...,aV} ,若使用属性 a 对样本集合 D 进行划分,则会产生 V 个分支结点。那么其中第 v 个结点,包含了样本集合 D 在属性 a 上取值为 av 的样本子集,记为 Dv 。
根据前面的公式,可以很容易计算出 Dv 的信息熵 Ent(D) 。
根据属性划分后,样本数据集 D 被分到了各个子集中,那么理所当然,熵也会发生变化。现在想要求出划分之后的熵,跟划分前的熵作差就可以知道熵的变化值。这个熵的差值就意味着不确定性的减少,而我们希望这个差值能尽可能大。这个差值我们就叫做信息增益。
一般来说,在选择划分属性时,我们希望减少不确定性,那么信息增益要尽可能大。所以在划分时,会计算每个属性的信息增益,并选取最大值。
增益率定义为:
CART决策树算法中采用的就是基尼指数。
在决策树生成过程中,对每个结点在划分前进行估计。若当前结点划分后不能使决策树的泛化性能有所提高(一般来说是,在交叉训练集中表现得更好),则停止划分并把当前结点标记为叶节点,类别就去出现次数最多的那个类别。
从训练集中生成好了一个完整的决策树之后,然后自底向上对非叶结点进行测试。若将该节点对应的子树换成叶节点,能带来决策树泛化性能的提升(划分前后的准确率提高),则将该指数替换为结点。
决策树的属性并不只有离散值,也可能出现属性是一个连续值的情况。由于连续属性的可取值数目不再是有限的,所以不能再根据连续属性的可取值来划分结点。
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 个元素的候选划分点集合:
有时会遇到不完整的样本,即样本的某些属性值有缺失。但是有时,这些属性值虽然缺失了一部分,但却对训练结果有好的影响。所以不能简单地就丢弃掉这些数据。
给定训练集 D 和属性 a ,令 D˜ 表示 D 在属性 a 上没有缺失值的样本子集。
假定属性 a 有 V 个可取值 {a1,a2,...,an} ,令 Dv˜ 表示 D˜ 中在属性 a 上取值为 av 的样本子集, Dk˜ 表示 D˜ 中属于第 k 类 (k=1,2,3...,|γ|) 的样本子集。
显然有:
决策树算法的原理不算特别复杂,主要还是在编程。下次再去整理下程序。
(ง •̀_•́)ง