【机器学习】决策树及Bagging, Random Forest和Boosting模型融合

来源:互联网 发布:前复权和后复权 知乎 编辑:程序博客网 时间:2024/04/28 08:06

前言

一晃一个月没写博客了。懒癌又犯了TT。
之前提到过,写博客是为了记录实习中学到的点滴。博主在某家做travelling IT solution的公司实习。公司核心业务还是做Global Distribution System的。我们部门做的是收益系统。我们小组的工作就是模拟运行收益系统。寻找能够提高收益的最佳参数设定。于是产生一些数据。实习的任务就是寻找最优化的参数来提高收益。我把它当做一个回归问题来做。把不同的参数设置当做其中features,训练出模型,得到收益变化。通过这些变化反过来寻找收益最大时的参数,把这个参数当做最佳参数。说起来有点绕了,简单讲就是一个回归问题。然后尝试了不同的算法,效果都不是特别好。其中Random Forest Regression能得到最好的结果。既然实际中运用到基于决策树的算法了,那就反过来记录一下咯。反正现在代码正在跑着,一两个小时内没事做,就来码码字咯。

决策树(Decision Tree)

随便一搜就能搜出很多大牛们的博客介绍决策树的。决策树可以计算回归和分类的问题。直观简单容易理解。我偷一个斯坦福大学Statistical Learning PPT上的一个例子吧(图不好看,但是博主喜欢篮球)。这个例子讲的是预测篮球运动运收入的问题。那么怎么预测运动员们的收入呢?在训练数据集里我们有运动员的打球时间:years,运动员过去几年的进球数(hits, 不知道hits是不是进球数的意思),走步次数(walks,不知道啥意思,我就自以为是猜是走步)等。(不要骂我,英文水平渣) 我们可以把训练数据进行分割。如图所示,年龄小于4.5是第一个分割节点。把所有球员工作年龄小于4.5年的放到图的左边分支,大于等于4.5年的放到右边。一个点产生两个分支(我们也可以设置多个分支)。然后对于打球时间小于4.5年的和大于4.5年的接着问第二个问题进行分割。比如对于大于4.5年的运动员接着根据他们的进球数进行分割。以此递归类推。最后数据越分越少,最后我们就建成了一棵树。树的末端叫做叶子。最后每一个运动员都会分到一个的叶子节点上,一个叶子节点可以有一个或者多个运动员。这个例子是一个回归问题,我们可以取分到同一个叶子点的所有运动员的收入平均值作为最后结果。对于分类问题,每个叶子是一个类别,如果分到这个叶子点的数据类别不一致,一般取个数最多的类作为这个叶子的输出类。

理论

决策树很通俗直观哈。我们在一次次按条件将训练数据分割的过程,就是一个训练的过程。就像我们不停地问问题,不停地用排除法,最后得出结果。这好像没有涉及到什么高深的数学问题啊。但是想想我们应该如何问问题呢?问问题的先后顺序,为什么要选择years<4.5呢?这部分就涉及到算法了。决策树有很多算法,比如常见的ID3, C4.5,C5, CART等等。这里我就偷懒简单介绍下ID3。ID3是用于解决分类问题(文章逻辑不严谨啊,上面的例子是关于回归问题的哈)。ID3是基于信息增益的算法。另外C4.5是基于信息增益率的算法,CART用的是Gini指数。这里只介绍熵,信息增益的概念。
(补充下各个决策树算法之间的区别)

  • ID3: 用于分类问题,并且要求features是 分类的(categorical)。算法基于信息增益
  • C4.5 : 用于分类问题,改进了ID3 features只能是分类的限制。算法基于信息增益率
  • C5:用于分类问题,C4.5的升级版
  • CART:用于分类或者回归问题,基于Gini指数(变量的不纯性度量)

熵 (Entropy)

大学学信息论的时候觉得好多东西用不上。觉得国内理论太多了,实践太少(对于动手能力强的牛人除外,对于我这样的小渣渣确实没机会动手)。后来做点项目读点paper才发现,好多基础知识非常重要。熵是用来描述信息的不确定性。不确定性越高值越大。香农大师天才地用一个公式来度量信息:

这里写图片描述
(截图来自Wikipedia,貌似用H表示熵更常用,这里不管,copy下)f表示的是事件的概率。

信息增益(Information Gain)

信息增益就是指信息量的增加,也可以理解为信息不确定性的减少。在我截图的公式中。可以理解为:
事件T在a条件下的信息增益 = 事件T的不确定的减少 = 事件T原来的熵 - 事件T在a条件上的熵。

这里写图片描述 (PS:此处本应该解释下怎么计算条件熵)

ID3

ID3算法的本质就是在每次分割数据的时候,选取信息增益最大的问题作为分割条件。我们先计算数据集每一个特征的信息增益。选取信息增益最大的特征作为决策树的根节点,该特征有几个取值,根节点就会有几个分支,每一个分支都会产生一个新的数据子集,余下的过程就是对每个子集再重复计算该子集每个特征的信息增益,直至子数据集都属于同一类。

优缺点

相对于其他算法,决策树的优点有:

  • 决策树简单,好解释,我们容易理解决策树
  • 对数据要求更低,不需要归一化,不需要数据拥有相同类型,可以处理数值也可以处理类别数据(要注意的是scikit-learn包实现的决策树算法,要求数据是数值类型的)
  • 决策树不需要把有多个类别的变量ont-hot encoding处理

决策树的缺点就是它的精确度和其他算法相比较而言比较低,overfitting比较严重。

剪枝(pruning)

剪枝的目的是为了减少overfitting。简要介绍下几种剪枝方法:

  • 预剪枝(prepruning),及早的停止树增长。当已建立的树满足某个要求的时候,停止训练数据。比如当节点的数据集的数据个数小于10的时候,终止算法。
  • 后剪枝 (postpruning),在已生成过拟合决策树上进行剪枝,可以得到简化版的剪枝决策树
  • 代价剪枝 (Cost complexity pruning)。copy了下图公式。只是想说明代价剪枝涉及到一个参数α。这需要cross validation寻找最佳值。

    这里写图片描述

剪枝的过程非常重要,有人说剪枝不生成树的过程更重要。另外scikit-learn (0.17.1)暂不支持剪枝操作。

模型融合

我们可以通过模型融合大大提高决策树的精确度。一个决策树是弱的,整合多个弱模型能够构造一个强的模型,三个臭皮匠顶个诸葛亮。

Bagging

Bagging 是 Bootstrap aggregating的缩写。思路就是重复取样,相同训练的数据多了之后,能够减少结果的方差。那怎么重复取样呢?假设原始训练数据量是n。我们从原始数据中有放回地随机抽取训练数据。抽取的数据量是n’ (n’ <= n)。用这个抽取的数据训练第一个决策树。用同样的方法我们做k次有放回抽取,训练k个决策树。在预测的时候,我们把测试集放到每一个决策树中预测,最后对所有决策树的结果做平均处理(回归),或者投票取最多的结果(分类)。
当然,我们可以设置重复取样的比例。另外要注意的时候,训练每棵树的时候,把训练数据的所有features都用上啦。

Random Forest

随机森林,顾名思义就是由很多决策树组成的森林。随机意味着每棵树之间没有任何联系,都是独立的。Random Forest其实就是在Bagging的基础上加一个条件。它也是按照Bagging的方法重复取样,但是抽取的数量和样本总量相等 (n)。但是在训练树的时候并不是把所有features都用上。假设我们总共有M个features。每次训练一棵树的时候,我们随机抽取其中的m(m << M)个features进行训练。随机森林中的树不需要进行剪枝操作。因为样本的抽取,特征的抽取已经保证了随机性,大大减少了overfitting的可能性。

Boosting

Boosting有很多种,比如AdaBoost(Adaptive Boosting), Gradient Boosting等。
Boosting也是集合了多个决策树,但是Boosting的每棵树是顺序生成的,每一棵树都依赖于前一颗树。顺序运行会导致运行速度慢。
这里简要介绍下AdaBoost的思想,而不去阐述Boosting决策树的构建构建方法和数学公式推导。
AdaBoost,运用了迭代的思想。每一轮都加入一个新训练一个预测函数,直到达到一个设定的足够小的误差率。

  • 开始的时候每一个训练样本都被赋予一个初始权重,用所有样本训练第一个预测函数。计算该预测函数的误差,然后利用该误差计算训练的预测函数的权重系数(该预测函数在最终的预测函数中的权重,此处忽略公式)。接着利用误差更新样本权重(此处忽略公式)。如果样本被错误预测,权重会增加;如果样本被正确预测,权重会减少。通过权重的变化,使下轮的训练器对错误样本的判断效果更好。
  • 以后每轮训练一个预测函数。根据最后得出的预测函数的误差计算新训练的预测函数在最终预测中的权重,然后更新样本的权重。权重更新之后,所有样本用于下轮的训练。
  • 如此迭代,直到误差小于某个值。

PS: 这里涉及到两个权重,每轮新训练的预测函数在最终预测函数中所占的权重和样本下一轮训练中的权重。这两个权重都是关于 每轮训练的预测函数产生的误差 的函数。这里就不copy了。

总结

整了好久才撸出来这么点东西,才知道博客大牛们是多么地不容易。
Bref,这边博文很不严谨地介绍了决策树的原理。简单谈了谈决策树的优缺点。因为决策树效果不好,overfitting严重。于是我们引入了模型融合。

Bagging的训练集的选择是重复随机的,训练集样本数一般小于总样本数。各个训练集之间相互独立的,而且训练样本没有权重。Bagging的各个预测函数也没有权重,预测函数之间没有联系。另外每次训练的时候用上了所有的特征。Bagging可以并行生成,速度快。

相反Boosting的训练集是有权重的且利用全部训练集,每轮训练的预测函数的训练集和之前的学习结果有关,各个预测函数只能顺序生成且每轮生成的预测函数都有权重,所以非常耗时。同时又overfitting的风险。

和Bagging相对比而言,Rand Forest 有放回 的选取和训练样本总数相同的样本来训练,另外只选取了样本的部分特征。一般效果比Bagging好。
好了,就先这样吧。

1 0