采用递归的分治法构造决策树,每次依据最优划分属性的属性值,将当前层的全集S划分为若干个子集,并采用相同方法对子集构造决策树。决策树算法包括两部分:树的构建和树的剪枝。
怎样的决策树才是最优的?
基本的原则是使最后构造出的决策树规模最小。基于这个基本原则,我们启发式地定义规则为使分割后得到的子节点纯度最大。于是属性选择规则问题就转化为了纯度定义的问题。
利用熵(Entropy)的概念去描述“不纯度”,熵值越大,说明这个节点的纯度越低:当节点的类别均匀分布时,熵值为1;当只包含一类时,熵值为0。信息增益存在的问题是总倾向于选择包含更多取值的属性,因为属性的取值越多,其分割后的子节点纯度可能越高。为了避免这个问题,我们引入了信息增益率(GainRatio)的选择指标。信息增益率存在的问题是:倾向于选择分割不均匀的分裂方法,举例而言,即一个拆分若分为两个节点,一个节点特别多的实例,一个节点特别少的实例,那么这种拆分有利于被选择。为了克服信息增益和信息增益率各自的问题,一种解决方案如下:首先利用信息增益概念,计算按照每一个属性进行分割的信息增益,获得平均信息增益;选出信息增益大于平均值的所有属性集合,对该集合计算信息增益率,选择其中信息增益率最大的属性进行决策树分裂。
信息增益的计算公式:
Gain(A)= Info(S) – InfoA(S)
Info(S)= -Pi*log2(Pi),i是对集合S的所有最终判定类别进行枚举
InfoA(S)= Pj*Info(Sj),j是对属性A的所有属性值进行枚举
其中Pi是类别i出现的概率,用Si/S来近似;Pj是对应属性值aj的集合占全集的比例,用Sj/S来计算。
信息增益率的计算公式:
GainRatio(A)= Gain(A) / SplitInfoA(S)
SplitInfoA(S)= -Pj*log(Pj),j是对属性A的所有属性值进行枚举,Pj含义同上
过拟合问题(Overfitting)
过拟合问题是对训练数据完全拟合的决策树对新数据的预测能力较低。为了解决这个问题,有两种解决方法。第一种方法是前剪枝(prepruning),即事先设定一个分裂阈值,若分裂得到的信息增益不大于这个阈值,则停止分裂。第二种方法是后剪枝(postpruning),首先生成与训练集完全拟合的决策树,然后自下而上地逐层剪枝,如果一个节点的子节点被删除后,决策树的准确度没有降低,那么就将该节点设置为叶节点(基于的原则是Occam剃刀:具有相似效果的两个模型选择较简单的那个)。
缺点:传统的决策树算法(ID3,C4.5)需要把训练数据放在主存,否则频繁的磁盘读写将导致低下的效率。一种可伸缩的决策树算法,包括SLIQ和SPRINT,RainForest,BOAT(BootstrappedOptimistic Algorithm for Tree Construction,可以根据训练数据的变化而更新决策树,不用重新构造决策树)。
性能分析:
传统的决策树构造方法,在构造每一层结点的时候,都需要对训练数据扫描一次。时间复杂度为O(n*|S|*log|S|),其中log以2为底,n为属性的个数,|S|为训练样本的个数。
伪代码实现:
/// @brif 构造一棵决策树,并返回决策树的根结点
/// @param S 熟练数据集
/// @param attri_list 属性集
/// @return 决策树的根结点
Node* Generate_decision_tree(DataSet* S, AttriList* attri_list)
{
Node* node;
if(Is_leaf(S, attri_list)) { // 判断当前状态是否为叶子结点
Set_as_leaf(node); // 把node置为叶子结点
return node;
}
Select_splitting_attri(S, attri_list, node); // 选取划分属性,并将划分信息写到node中
Remove_attri(attri_list, node->attri); // 删除剩余属性集中选取的划分属性
foreach(attri_value in node->attri) { // 根据划分属性的属性值,将全集S分成若干子集分别构造决策树,这里就是决策树的分治部分
Construct_subset(S, node->attri, attri_value, s); // 根据选取的属性值构造训练子集
Node* subnode;
if(s == null) { // 子集为空,添加叶结点,可对S采用多数表决法
Vote_for_decision(S, subnode);
} else {
subnode = Generate_decision_tree(s, attri_list);
}
Add_subnode(node, subnode);
}
Add_attri(attri_list, node->attri); // 需要将删除的属性恢复,因为attri_list为共享区
return node;
}
ID3算法分析
ID3算法是从假设空间中选择一个拟合训练数据的假设,其假设空间是所有可能的决策树集合。但是它采用的是贪心策略,采用爬山法,且在寻找拟合函数的过程中没有回溯机制,因此无法避免爬山法在登山过程中选取局部最优而不是全局最优的问题。以下是几点分析:
1.假设空间包含所有的决策树,因此避免了搜索不完整假设间时可能不包含目标函数的风险;
2.在遍历决策树时,仅维护单一的当前假设,因此失去了表示所有一致假设所带来的优势(例如同其他一致假设进行最优性比较)
3.不进行回溯,应该无法避免爬山法带来的可能收敛到局部最优的问题
4.采用全局数据,降低了个别错误样本带来的错误敏感性,容错能力强
Reference
http://blog.sina.com.cn/s/blog_618985870101ibjj.html
韩家炜,《数据挖掘:概念与技术》
Mitchell,《机器学习》