决策树相关算法介绍(ID3/C4.5/CART)

 

什么是决策树

决策树是一种非常基础又常见的机器学习模型。

一棵决策树(Decision Tree)是一个树结构(可以是二叉树或非二叉树),每个非叶节点对应一个特征,该节点的每个分支代表这个特征的一个取值,而每个叶节点存放一个类别或一个回归函数。

 

使用决策树进行决策的过程就是从根节点开始,提取出待分类项中相应的特征,按照其值选择输出分支,依次向下,直到到达叶子节点,将叶子节点存放的类别或者回归函数的运算结果作为输出(决策)结果。

 

决策树的决策过程非常直观,容易被人理解,而且运算量相对小。它在机器学习当中非常重要。

 

构建决策树

1. 准备若干的训练数据(假设 m 个样本);

2. 标明每个样本预期的类别;

3. 人为选取一些特征(即决策条件);

4. 为每个训练样本对应所有需要的特征生成相应值——数值化特征;

5. 将通过上面的1-4步获得的训练数据输入给训练算法,训练算法通过一定的原则,决定各个特征的重要性程度,然后按照决策重要性从高到底,生成决策树.

 

那么训练算法到底是怎么样的?

决定特征重要程度的原则又是什么呢?

下面介绍决策树的几种常用算法

 

决策树的构造过程是一个迭代的过程。每次迭代中,采用不同特征作为分裂点,来将样本数据划分成不同的类别。被用作分裂点的特征叫做分裂特征。选择分裂特征的目标,是让各个分裂子集尽可能地“纯”,即尽量让一个分裂子集中的样本都属于同一类别

 

ID3算法 (Iterative Dichotomiser)

核心思想:以信息增益为度量,选择分裂后信息增益最大的特征进行分裂

遍历所有特征,对于特征A:

1.计算特征A对数据集D的经验条件熵H(D|A)

2.计算特征A的信息增益:

g(D,A)=H(D) – H(D|A)

3.选择信息增益最大的特征作为当前的分裂特征

4.迭代

 

ID3优点是理论清晰、方法简单、学习能力较强,但也存在一些缺点:

(1)只能处理分类属性的数据,不能处理连续的数据;

(2)划分过程会由于子集规模过小而造成统计特征不充分而停止;

(3)ID3算法在选择根节点和各内部节点中的分支属性时,采用信息增益作为评价标准。信息增益的缺点是倾向于选择取值较多的属性,在有些情况下这类属性可能不会提供太多有价值的信息。

 

C4.5算法

核心思想:以信息增益率为度量

C4.5是ID3的升级版,针对ID3的缺点做了优化。

C4.5算法选用信息增益率(Gain Ratio)——用比例而不是单纯的量——作为选择分支的标准。信息增益率通过引入一个被称作分裂信息(Split Information)的项,来惩罚取值可能性较多的特征,这有效避免了ID3一般会优先选择取值种类较多的特征作为分裂特征的不足。

针对ID3不能处理取值在连续区间的特征 ,C4.5做了以下优化

1.把需要处理的样本(对应整棵树)或样本子集(对应子树)按照连续变量的大小从小到小进行排序。

2.假设所有 m 个样本数据在特征上的实际取值一共有 k(k<=m)个,那么总共有 k-1 个可能的候选分割阈值点,每个候选的分割阈值点的值为上述排序后的特征值中两两前后连续元素的中点。根据这 k-1 个分割点把原来连续的一个特征,转化为 k-1 个 Bool 特征。

3.用信息增益率选择这 k-1 个特征的最佳划分

 

CART算法(Classification and Regression Tree )

核心思想:以信息增益率为度量

ID3 和 C4.5 构造的都是分类树。还有一种算法,在决策树中应用非常广泛,它就是 CART 算法。

CART 算法的运行过程和 ID3 及 C4.5 大致相同,不同之处在于:1. CART 的特征选取依据不是增益量或者增益率,而是 Gini 系数(Gini Coefficient)。每次选择 Gini 系数最小的特征作为最优切分点。2. CART 是一棵严格二叉树。每次分裂只做二分

 

决策树过拟合优化

决策树对训练属于有很好的分类能力,但对未知的测试数据未必有好的分类能力,泛化能力弱,即可能发生过拟合现象。决策树应对过拟合的方法一般通过剪枝。

 

剪枝

剪枝 (pruning)是决策树学习算法对付"过拟合"的主要手段.在决策树学习中,为了尽可能正确分类训练样本,结点划分过程将不断重复,有时会造成决策树分支过多,这时就可能因训练样本学得"太好"了,以致于把训练集自身的一些特点当作所有数据都具有的一般性质而导致过拟合.因此,可通过主动去掉一些分支来降低过拟合的风险.

 

决策树剪枝的基本策略有"预剪枝" (prepruning)和"后剪枝 "(post"pruning) [Quinlan, 1993]. 预剪枝是指在决策树生成过程中,对每个结点在划分前先进行估计,若当前结点的划分不能带来决策树泛化性能提升,则停止划分并将当前结点标记为叶结点;后剪枝则是先从训练集生成一棵完整的决策树,然后自底向上地对非叶结点进行考察,若将该结点对应的子树替换为叶结点能带来决策树泛化性能提升,则将该子树替换为叶结点.

三种决策树的剪枝过程算法相同,区别仅是对于当前树的评价标准不同:信息增益、信息增益率、基尼系数

 

剪枝总体思路:

由完全树T0开始,剪枝部分结点得到T1,再次剪枝部分结点得到T2…直到仅剩树根的树Tk;在验证数据集上对这k个树分别评价,选择损失函数最小的树Tα

 

代码:

 

import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
from sklearn import model_selection

def load_data():
   '''
   加载用于分类问题的数据集。数据集采用 scikit-learn 自带的 iris 数据集
   '''
   iris = datasets.load_iris()  # scikit-learn 自带的 iris 数据集
   X_train = iris.data
   y_train = iris.target
   return model_selection.train_test_split(X_train, y_train, test_size=0.25,
                                            random_state=0, stratify=y_train)
   # 分层采样拆分成训练集和测试集,测试集大小为原始数据集大小的 1/4

def mytest_DecisionTreeClassifier(*data):
  
   X_train, X_test, y_train, y_test = data
   clf = DecisionTreeClassifier()
   clf.fit(X_train, y_train)

   print("Training score:%f" % (clf.score(X_train, y_train)))
   print("Testing score:%f" % (clf.score(X_test, y_test)))    
 
if __name__ == '__main__':
   X_train, X_test, y_train, y_test = load_data()  # 产生用于分类问题的数据集
mytest_DecisionTreeClassifier(X_train, X_test, y_train, y_test)  
# 调用 mytest_DecisionTreeClassifier

 

本文介绍了决策树的实现的经典算法及剪枝优化相关知识,希望有所帮助。


关注-微-公众号【学习与成长资源库】获取更多免费学习资料

 

参考

Python大战机器学习

邹博 机器学习视频课

李航 统计学习方法

周志华 机器学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长青_416686950

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值