Decision Tree 决策树 - ID3, C45, C50, CART...

原创 2015年07月09日 17:47:24
1. 是什么

决策树是最简单的也是最具解释性和表达性的一种机器学习算法,既可以处理分类问题(ID3,C45,C50),也可以处理回归问题(CART)。

它是根据特征(feature)的值逐步把数据分类,直到所有的叶子节点属于同一个类型结束。注意决策树都是贪婪的。


2. 关键概念

1. 如何确定哪个特征被优先选择用来分类。

根据某一个特征划分数据集,其划分前后信息熵会有变化。优先选择的特征是让给让信息熵变化最大或者信息熵增益比最大的特征。

不过,从另外一方面来说,也要避免选择日期或者非常特殊的特征来做决策点,因为这些特征不具备任何的泛化能力。

2. 如何避免过拟合。

对于决策树来说,如果树的高度过高,或者某个叶子节点的数据特别少,或者叶子节点非常多(后两者有关联),就有可能是过拟合,在匹配被预测数据的时候就不会有很好的性能。避免决策树学习中的过度拟合问题,通常通过两种方法:
(1)及早停止树增长,比如发现树的高度过高,叶节点过多,或者节点内数据过少。这是sci-kit learn库目前的做法。
(2)通过后剪枝减少决策树的节点的个数。
尽管上面第一种方法可能看起来更直接,但是对过度拟合的树进行后修剪被证明在实践中更成功。这是因为在第一种方法中精确的估计何时停止树增长很困难。后剪枝的算法基本上就是合并同一个根节点下面所有的叶节点成为一个大的节点,而选择哪些节点做合并则需要根据节点内部数据个数。


3. 算法分支(详情参见http://scikit-learn.org/stable/modules/tree.html)
  • ID3

选取能够得到最大信息增益(information gain)的特征为数据划分归类,直到全部划分结束而不对树的规模进行任何控制。

等树生成之后,执行后剪枝。

信息增益的潜在问题是,比如有一个数据集含有一个特征是日期或者ID,则该特征会得到最大的信息增益,但是显然在验证数据中不会得到任何的结果。C45的信息增益比就是解决这个问题的。

  • C45
选取能够得到最大信息增益率(information gain ratio)的特征来划分数据,并且像ID3一样执行后剪枝。
是ID3的后续版本并扩展了IDC的功能,比如特征数值允许连续,在分类的时候进行离散化。
信息增益率:
“Gain ratio takes number and size of branches into account when choosing an attribute, and corrects the information gain by taking the intrinsic information of a split into account (i.e. how much info do we need to tell which branch an instance belongs to).”
  • C50
这是最新的一个版本,是有许可的(proprietary license)。比之C45,减少了内存,使用更少的规则集,并且准确率更高。
  • CART
CART(Classification and Regression Trees)分类回归树,它使用基尼不纯度(Gini Impurity)来决定划分。Gini Impurity和information gain ratio的理解和区分在这里:
http://stats.stackexchange.com/questions/94886/what-is-the-relationship-between-the-gini-score-and-the-log-likelihood-ratio。
它和C45基本上是类似的算法,主要区别:1)它的叶节点不是具体的分类,而是是一个函数f(),该函数定义了在该条件下的回归函数。2)CART是二叉树,而不是多叉树。

4. 怎么用

sci-kit learn提供决策树,是基于优化的CART算法,使用方便简单,但是有两个问题:1)不如C50优化;2)sci-kit learn库并没有实现后剪枝(截至最新版0.16.0),所以防止过拟合的办法都是提前停止生长的方法,可以通过设置参数的方式控制。详情参加:http://scikit-learn.org/stable/modules/tree.html


使用:

from sklearn import tree
clf = tree.DecisionTreeClassifier() or clf = tree.DecisionTreeRegressor
clf = clf.fit(X, Y)
clf.predict([[..]])
clf.predict_proba([[..]])
(其中clf就是最终的分类器,而X是输入数据,Y是label。)


类和函数的原型:

class sklearn.tree.DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, class_weight=None)

输入参数展开说:

criterion: 划分的规则,默认是gini。“gini” = Gini Impurity,取值在0-1之间。“entropy” = 信息增益(information gain)。基尼系数通常是确定平衡的一个指数,用于评价一个国家的收入是否分配不均衡。这里的基尼不纯度基本上恰好相反:值最小,=0,表明分类之后的元素都归于某一类,越纯(实际上对应的基尼系数应该是越不平衡);越趋近于1,表明元素均匀的分散到各个分类里面。
splitter:划分节点的策略,默认是best,算法会根据criterion来选择最好的feature做分割。可以设置random,算法会随机选择feature做分割;但是实际上,也并非完全的随机,算法也会做一些避免造成泛化能力丢失的处理。
max_features: 划分的时候需要考虑多少特征,或者全部(默认值)或者一个子集。
max_depth: 最大树深度。避免过拟合的。
min_samples_split: 内部节点上,每一个节点至少需要有的sample个数。避免过拟合的。
min_samples_leaf:  叶子节点上,每一个节点至少需要有的sample个数。避免过拟合的。
min_weight_fraction_leaf: 没研究。
max_leaf_nodes: 最大叶子节点个数。他和max_depth互斥。避免过拟合的。
class_weight:分类的权重。没研究。
random_state : 随机种子,为splitter服务的。如果splitter=random,那么在对同一组数据做两次预测的时候,会有可能造成决策树不一样(很可能),其原因是使用了不同的随机种子(random_state),所以如果一直记录下来随机种子值并一直使用该值的话,就不会出现多次预测结果不一样的问题。

结果展开说:

tree_ : Tree 对象(sklearn.tree._tree.Tree),二叉树。根据这个tree_对象,可以还原整个决策树的决策过程。关于tree_的细节,可以参考sklearn的官网,如何把tree可视化,可以参照stackoverflow的问答(参考链接在后面):

    from sklearn import tree

    from StringIO import StringIO

    import pydot (需要首先安装pydot库)

    dot_data =StringIO()

    tree.export_graphviz(clf,out_file=dot_data)

    graph =pydot.graph_from_dot_data(dot_data.getvalue())

   graph.write_pdf("./iris.pdf")


classes_ : 分类的label。
n_classes_ : 分类个数。
feature_importances_ : 特征重要度。越大越重要,表明越是被优先选出来的。

max_features_ : 参与决策树的特征数。

5. 应用场景和限制

是监督的分类和回归算法。对噪声点的容忍性非常好。性能比较好。贪婪。

详情参阅:http://scikit-learn.org/stable/modules/tree.html


6. 参考

http://scikit-learn.org/stable/modules/tree.html

http://blog.csdn.net/google19890102/article/details/28611225

http://underthehood.blog.51cto.com/2531780/610442

http://blog.csdn.net/cyningsun/article/details/8735169

http://stackoverflow.com/questions/25274673/is-it-possible-to-print-the-decision-tree-in-scikit-learn

机器学习 -- 决策树C45算法使用实例

机器学习 -- 决策树C45算法使用实例
  • csharp25
  • csharp25
  • 2016年07月02日 15:14
  • 2176

机器学习算法之决策树算法

该节主要是把《机器学习实战》书上第三章关于决策树的相关代码照样子实现了一遍。对其中一些内容作了些补充,对比ID3与C45区别,同时下载了一个大样本集实验决策树的准确率。首先,对于决策树的原理,很多很好...
  • on2way
  • on2way
  • 2015年07月31日 20:47
  • 2968

机器学习之决策树(Decision Tree)&随机森林(Random forest)

决策树是机器学习中最接近人类思考问题的过程的一种算法,通过若干个节点,对特征进行提问并分类(可以是二分类也可以使多分类),直至最后生成叶节点(也就是只剩下一种属性),而随机森林是基于决策树过拟合提出的...
  • July_sun
  • July_sun
  • 2016年11月25日 19:27
  • 4824

机器学习与R之决策树C50算法

决策树 经验熵是针对所有样本的分类结果而言 经验条件熵是针对每个特征里每个特征样本分类结果之特征样本比例和 基尼不纯度 简单地说就是从一个数据集中随机选取子项,度量其被错误分类到其他分组里的概...
  • q383700092
  • q383700092
  • 2016年07月02日 11:39
  • 3873

python实现机器学习之随机森林

这几天一直在看随机森林。可以说遇到任何一个有关预测的问题。都可以首先随机森林来进行预测,同时得到的结果也不会太差。在这篇文章里我首先会向大家推荐几篇写的比较好的博客。接着会将我觉得比较好的例子使用py...
  • LULEI1217
  • LULEI1217
  • 2015年11月02日 10:17
  • 25660

DecisionTreeClassifier和DecisionTreeClassifier 重要参数调参注意点

DecisionTreeClassifier和DecisionTreeClassifier 重要参数调参注意点     为了便于比较,这里我们用表格的形式对DecisionTreeClassif...
  • akon_wang_hkbu
  • akon_wang_hkbu
  • 2017年08月27日 17:21
  • 413

决策树与随机森立案(python code)---------------------------机器学习系列(二)

前面一篇大致讲解了一下有关决策树与随机森林的理论部分,这一篇我们就来电实际的,讲一下python怎么实现决策树与随机森林的,这部分的code有一点简单,应该可以更好的理解这个算法。         ...
  • Eason_oracle
  • Eason_oracle
  • 2017年06月27日 11:47
  • 440

Python sklearn库中决策树tree.DecisionTreeClassifier()函数参数介绍

Python sklearn库中决策树tree.DecisionTreeClassifier()函数参数介绍
  • li980828298
  • li980828298
  • 2016年04月17日 13:12
  • 11725

sklearn决策树 DecisionTreeClassifier建立模型, 导出模型, 读取

print(__doc__) # Import the necessary modules and libraries import numpy as np import time from skl...
  • zzllabcd
  • zzllabcd
  • 2016年10月10日 16:57
  • 4704

机器学习算法之四:5分钟上手Decision Tree

案例:这个数据用身高和体重来界定胖瘦。如下文字档(4.tree.txt),三个栏位各代表身高(m)、体重(kg)与胖瘦(thin/fat)。 问题:现在有一身高1.5m与体重99kg的数据,请问是胖是...
  • u011775523
  • u011775523
  • 2016年10月08日 17:03
  • 1132
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Decision Tree 决策树 - ID3, C45, C50, CART...
举报原因:
原因补充:

(最多只允许输入30个字)