树模型(1)-入门指南

原文地址:https://www.analyticsvidhya.com/blog/2016/04/complete-tutorial-tree-based-modeling-scratch-in-python/

翻译时间:2017年4月

翻译作者:FBeetle


简介

基于树的学习算法被认为是非监督学习方法中最好的并且是最常用的方法之一。基于树的方法使得模型的精确率很高,很稳定和容易解释。与线性模型不同,基于树的模型能够很好地表达非线性关系,它适合用来解决我们遇到的任何问题(分类和回归问题)。

决策树、随即森林、梯度提升等方法在各种数据科学问题中被广泛使用, 因此对于每一个数据分析人员(以及数据新手),学习使用这些算法并使用它们进行建模是非常重要的。

该教程的目的是帮助初学者从头开始学习基于树的建模。学完本教程的人,预计可以熟练使用基于树的算法和建模。

注:本教程不需要实现了解机器学习知识,然而基础的R或者Python知识是非常有帮助的。了解R或者Python可以参考完整R教程和Python教程。

内容列表

1、什么是决策树?决策树是如何工作的?
2、回归树与分类树
3、树如何决定在哪里分裂?
4、树模型的关键参数是什么?决策树中如何避免过拟合?
5、树模型比线性模型更好么?
6、在R和Python中使用决策树
7、基于树模型的集成方法有哪些?
8、Bagging方法及工作原理
9、Random Forest模型及工作原理
10、GBM与XGboost哪个更强大?
11、在R和Python中使用GBM
12、在R和Python中使用XGboost
13、在哪里练习使用这些模型?

1、什么是决策树?决策树是如何工作的?

决策树是一种监督学习算法(具有预定义的目标变量),它主要用于分类问题,输入和输出变量可以是离散值或连续值。在决策树中,我们根据输入变量中最具有区分性的变量,把数据集或样本分割为两个或两个以上的子集合。


例如:
假设我们有30名学生的样本,有三个变量分别是:性别(男孩/女孩)、尺码(IX/X)、身高(5/6英尺)。这30个人中,15个闲暇的时候玩板球。现在我想建立一个模型预测谁会在空闲时间玩板球?在这个问题中,我们需要根据上述三个变量中最有区分性的那些变量, 分离出那些闲暇时间玩板球的同学。
这正是决策树可以提供帮助的,它会根据学生信息的三个属性识别目标学生,分离出那些闲暇时玩板球的同学。在下面的快照中,可以看到性别属性比其他两个属性更能够较好地区分一个人是否玩板球。


如上所述,决策树发现能最显著区分一个人是否玩板球的属性以及它的取值,该属性能够最好地区分不同的学生样本。现在的问题是,决策树是如何识别变量和进行分割学生样本的?做到这一点,决策树使用了多种算法,我们会在下一节介绍。

决策树的类型

决策树的类型区分是基于目标变量的类型,可以分为两类
1、离散变量决策树:具有离散型目标变量的决策树。例如在上述学生分类问题中,目标变量是学生是否玩板球,即“是”或“否”
2、连续变量决策树:具有连续型目标变量的决策树。
例如:假设我们的问题是要去预测一个客户是否会继续购买保险(是/否)。我们知道客户的收入是一个非常有用的变量,但是保险公司不知道每个客户的收入详情。现在我们知道收入是一个非常重要的变量,我们可以建立一个决策树,根据客户的职业、购买产品及其他信息,去预测一个客户的收入。这时候我们要预测的值是连续变量。

决策树相关的重要术语


让我们看一下在决策树中使用的基本术语:
1、根节点:它标识整个样本,会被进一步分割成两个或多个子集合。
2、拆分:将一个节点分割为两个或多个子节点的过程。
3、决策节点:当一个子节点进一步分裂成子节点的时候,它被称为决策节点。
4、叶子/终端节点:不会被分割的节点被称为叶子或终端节点。
5、剪枝:当我们移除掉决策节点的子节点时,这个过程成为剪枝。他是拆分的反过程。
6、分支/子树:整个树的子部分成为分支或子树。
7、父节点和孩子节点:被分割成子节点的节点成为子节点的父节点,子节点是父节点的孩子节点。
这些是决策树中常用的术语。我们知道每种算法都有优点和缺点,下面是一些我们应该知道的关键点

优点

1、易于理解:决策树的输出是非常容易理解的,即使是对于没有数据分析背景的人。它不需要任何统计知识去阅读和解释。它的图形标识非常直观,用户可以很容易地和他们的假设联系在一起。
2、在数据探索中非常有用:决策树是发现最相关的两个或多个变量关系的最快速的方式之一。在决策树的帮助下,我们可以创建新的具有更强预测能力的变量/特征,可以参考 这篇文章(提升回归模型的技巧)。它还可以用于数据探索阶段。例如,我们正在研究一个具有数百个变量信息的问题,决策树可以帮助我们确定最重要的哪些变量。
3、需要更少的数据清洗:相对于其他建模技术,决策树需要较少的数据清洗。它不会收到离群点和缺失值的特别大的影响。
4、数据类型不受约束:决策树可以处理数值型和离散型数据变量。
5、非参数方法:决策树是一个非参数方法。这意味着它不对数据的空间分布和分类结构做任何假设。

缺点

1、过拟合:过拟合是决策树最难处理的困难之一,这个问题通过设置模型参数和剪枝(下面讨论)来解决。
2、不适合于连续型变量:当处理连续数值型变量时,当决策树把连续变量划分成一系列离散值的时候会导致信息丢失。

2、回归树与分类树

我们都知道叶节点位于决策树的底部。这意味着决策树是通常是被倒置的,这样它的叶子在底部,根节点在顶部(如下所示)。

回归树和分类树的几乎一样工作,让我们看看他们的主要区别和相似之处。
1、当因变量(目标变量)是连续的时候使用回归树,当因变量(目标变量)是离散的时候使用分类数
2、对于回归树,训练数据从叶子节点获得的值是位于在该节点内的所有样本点的目标变量平均值。因此当一个新的数据样本到达该区域,我们会使用平均值作为该新样本点的预测值。
3、对于分类树,训练数据从叶节点获得的值是位于该节点内的所有样本点的目标变量的众数值。因此当一个新的数据样本到达该区域,我们会使用众数值作为该新样本点的预测值。
4、回归树和分类树都是将预测空间(独立变量)划分成不重叠的区域。为了简单起见,你可以把这些区域看作高维的盒子。
5、回归树和分类数都遵循自顶向下的贪婪方法,被称为递归二元分裂。我们称之为自顶向下,因为对于一个区域内的所有观测点,它从树的顶端开始陆续分裂为两个新的分支。它被称为贪心是因为该算法只关注当前分裂,不关注未来的可能会产生更好结果的分裂情况。
6、这种分裂过程一直持续直到达到用户定义的停止标准为止,例如,当每个节点的观测节点个数小于50的时候,我们可以让算法停止继续分裂。
7、对于回归树和分类树,在到达停止标准之前,分裂过程持续进行(直到完全分裂为每个节点只有一个样本点)。但是完全分裂的树很可能过拟合数据,导致对未知数据的预测准确率比较低。这就需要剪枝,剪枝是解决过拟合的一种技术,我们会在下一节中学习更多关于剪枝技术。

3、树如何决定在哪里分裂?

分列策略对树的准确率影响很大,回归树和分类树具有不同的决策标准。
决策树使用多种算法来决定分裂一个节点为两个或多个子节点。子节点的创建增加子节点的均匀性。换句话说,我们可以说对于目标变量的纯度增加。决策树根据所有可用变量,选择能产生最可能均匀的子节点的分列方式进行分裂。
算法的选择也是基于目标变量的类型。让我们看下决策树中最常用的四种算法:

基尼系数

基尼系数是指,如果我们从样本集中随机选择两个样本点,如果该样本集是纯的,那么这两个样本点属于相同的类的概率是1。
1、基尼系数适用于目标变量是诸如”成功“或”失败“的离散目标变量。
2、它表现为二元分裂。
3、基尼系数越高,数据越均匀。
4、CART(分类回归树)使用基尼系数创建二元分裂。

计算基尼系数

1、计算子节点的基尼系数,使用成功和失败的概率的平方和公式,(p^2+q^2)。
2、使用每个节点进行分裂的基尼分数加权作为该节点的基尼系数决定如何进行分裂。
例如:参考上面的例子,我们想要根据目标变量(是否玩板球)来分隔学生样本。下图中,我们使用两个输入变量性别和类变量。现在我们使用基尼系数来标识那种分裂方式能够产生更加均匀的子节点。

根据性别分裂:

1、计算子节点女性的基尼系数=(0.2)*(0.2) + (0.2)*(0.2) = 0.68
2、计算子节点男性的基尼系数=(0.65)*(0.65) + (0.35)*(0.35) = 0.55
3、计算根据性别分裂的加权基尼系数=(10/30)*0.68 + (20/30)*0.55 = 0.59

根据尺码分裂:

1、计算子节点IX尺码的基尼系数= (0.43)*(0.43)+(0.57)*(0.57)=0.51
2、计算子节点X尺码的基尼系数=(0.56)*(0.56)+(0.44)*(0.44)=0.51
3、计算根据尺码分裂的加权基尼系数=(14/30)*0.51+(16/30)*0.51 = 0.51
以上,我们可以看到根据性别分裂的基尼分数比根据尺码分裂的基尼系数要高,因此该节点将根据性别进行分裂。

卡方

卡方算法是找到子节点和父节点之间差别的统计意义。我们通过目标变量的观测值和期望值的标准化差异平方和来衡量。
1、卡方适用于目标变量值是注入”成功”或“失败”的离散目标变量。
2、它可以执行二分裂或多分裂。
3、卡方值越高,父节点和子节点之间差异的统计意义就越大。
4、使用公式计算每个节点的卡方。
5、卡方 = ((实际值 - 期望值) / 期望值)^(1/2)。
6、它产生的树称为CHAID(Chi-square Automatic Interaction Dector)

根据卡方分裂步骤:

1、通过计算成功和失败的偏差来计算单个节点卡方。
2、利用每个待分裂节点的成功和失败的卡方之和来及i算分裂的卡方。

例如:

让我们使用上面用来计算基尼系数的例子进行说明。

根据性别分裂

1、首先我们根据性别是否为女性进行处理,计算实际玩板球和不玩板球的人数,分别是2和8。
2、计算玩板球和不玩板球的期望值,这里它们都是5,因为父节点有50%的概率玩板球,女性一共10人。
3、计算偏差公式,实际值-期望值。计算玩板球(2-5=-3)和不玩板球(8-5=3)的值.
4、利用公式((实际值 - 期望值) / 期望值)^(1/2)计算一个节点玩板球和不玩板球的卡方,可以参考下表计算。
5、使用类似步骤计算男性节点的卡方值。
6、计算根据性别进行分裂的卡方。

根据尺码分裂:

根据尺码分裂执行相同的计算步骤,可以得到如下表格。

通过以上步骤可以发现,根据性别分裂的卡方值比根据尺码分裂的卡方值更加具有区分性。

信息增益

观察下面的图片,思考哪个点更容易描述,我敢肯定你的答案是C,因为它所有点的值都是相似的,你需要较少的信息去描述它。另一方面B需要多一些的信息才更容易描述,A相对于B和C需要最多的信息才能描述。换句话说我们可以说C是一个纯的节点,B是不那么纯的节点,A是更加不纯的节点。

现在我们可以得出这样的结论:纯度高的节点需要较少的信息描述,不纯的节点需要更多的信息描述。信息论中熵是用来衡量无序程度的这样一个指标。如果样本是完全均匀的那么熵是0,如果样本是50%-50%等分的,那么熵是1。
熵可以用如下公式计算:
这里p和q分别是节点成功或失败的概率(就是其中点分别属于两个类别的概率)。熵也可以应用于离散型目标变量,它选择相对于父节点和其他分列方式据有最小信息熵的分裂方案,熵越小,分裂方案越好。

根据信息熵进行分裂的步骤:

1、计算父节点的信息熵。
2、计算根据每个节点进行分裂的信息熵,计算所有子节点可能分裂的加权平均。

例如:

让我们使用这种方法计算对学生样本进行处理的最佳分裂。
1、父节点的信息熵为  -(15/30) log2 (15/30) – (15/30) log2 (15/30) = 1,他是一个纯节点(一半的人玩板球,一半的人不玩板球)。
2、女性节点信息熵为  -(2/10) log2 (2/10) – (8/10) log2 (8/10) = 0.72,男性节点的信息熵为 -(13/20) log2 (13/20) – (7/20) log2 (7/20) = 0.93
3、根据性别分裂的信息熵 = 子节点的信息熵加权 = (10/30)*0.72 + (20/30)*0.93 = 0.86
4、尺码IX的节点信息熵为 -(6/14) log2 (6/14) – (8/14) log2 (8/14) = 0.99,尺码为X的节点的信息熵为 -(9/16) log2 (9/16) – (7/16) log2 (7/16) = 0.99
5、根据尺码进行分裂的信息熵 = 子节点的信息熵加权 = (14/30)*0.99 + (16/30)*0.99 = 0.99
以上可以看到,根据性别分裂的信息熵是最低的,我们可以得到信息增益 = 1 - 信息熵。

减少方差

到目前为止我们讨论了针对离散目标变量的算法,减少方差是适用于连续型目标变量的算法(回归问题)。该算法选择标准差公式选择最佳分裂方式,具有最低方差作为分裂标准。

以上X-bar代表X均值,X是取值,n是取值个数。

计算方差的步骤

1、计算每个节点的方差。
2、计算每个分裂节点的加权平均防方差。

例如:

我们假设数值1标识玩板球,数值0标识不玩板球,按照这个步骤确定正确的分裂。
1、计算根节点的方差,平均值为 (15*1 + 15*0)/30 = 0.5,有15个取值1,15个取值0,方差为 ((1-0.5)^2+(1-0.5)^2+…. 15项 + (0-0.5)^2+(0-0.5)^2+…15项) / 30,可以写成 (15*(1-0.5)^2+15*(0-0.5)^2) / 30 = 0.25
2、女性节点的均值为 (2*1+8*0)/10=0.2,方差为  (2*(1-0.2)^2+8*(0-0.2)^2) / 10 = 0.16
3、男性节点的均值为 (13*1+7*0)/20=0.65,方差为 (13*(1-0.65)^2+7*(0-0.65)^2) / 20 = 0.23
4、根据性别分裂的方差 = 子节点方差加权 =  (10/30)*0.16 + (20/30) *0.23 = 0.21
5、尺码为IX的节点的均值为 (6*1+8*0)/14=0.43,方差为 (6*(1-0.43)^2+8*(0-0.43)^2) / 14= 0.24
6、尺码为X的节点的均值为 (9*1+7*0)/16=0.56,方差为 (9*(1-0.56)^2+7*(0-0.56)^2) / 16 = 0.25
7、根据尺码分裂的方差为 (14/30)*0.24 + (16/30) *0.25 = 0.25
以上可以看出,根据性别分裂比父节点方差更低,因此根据性别进行分裂。
到此为止,我们了解了决策树的基本知识,以及对树模型建模时选择最佳分裂的决策过程。正如我所说的决策树可以应用于分裂和回归问题中,让我们详细地了解这方面知识。

4、树模型的关键参数是什么?决策树中如何避免过拟合?

过拟合是对决策树建模过程面临的一个核心挑战。如果没有对决策树的限制条件集,它会在训练集上达到100%准确率,因为它在最坏的情况下会 把每个样本分配到一个节点上,因此防止过拟合是对树模型建模的关键,有两种方式防止过拟合:
1、对树的大小设置约束条件
2、对树进行剪枝
让我们简单讨论下这两个问题。

对树的大小设置约束条件

这可以通过使用用于定义树的各种参数来完成,首先让我们看一下决策树的基本结构。


用于定义树的参数进一步解释如下。下面描述的参数与工具无关,重要的是了解参数在树建模中的作用,这些参数在R和Python中均有。
1、节点分裂的最小样本数
定义为需要分裂的节点中包含的最小样本个数。
用于控制过拟合,较高的值可以防止模型学习特定样本相关的特征(即只有在这些特定样本中才有的特征)。
太高的值会导致欠拟合,因此需要使用CV(交叉验证)进行调参。
2、叶节点中的最小样本数
定义为叶节点需要的最小样本个数。
和节点分裂需要最小样本个数类似,用于控制过拟合。
通常对于正负样本分布不均衡的分类问题,会选择较低的值,因为少数类别的样本占比较高的区域会非常小(即大部分的树区域都被个别样本占据)。
3、树的最大深度
树的最大深度。
用于控制过拟合,较大的深度会允许模型学习到更多特定样本相关的特征。
应该使用CV方法进行参数调节
4、叶节点的最大数目
树的叶节点或终端节点的最大数目。
可以替代树的深度进行定义。深度为n的二叉树最多产生2^n个叶节点。
5、考虑分裂的最大特征个数
寻找最佳分裂方案的时候考虑的最大特征个数,这些特征是随机选择的。
根据经验,总特征数的根号个特征是最优的,但是我们应该检查多达30%~40%的特征总数时的分裂方案。
较高的值会导致过拟合,但是视具体情况而定。

树剪枝

如前面描述对树设置约束条件是贪婪的方法。换句话说,它会检查当前最佳分裂方案,直到发现满足特定停止条件。让我们考虑当你驾驶汽车时的如下情况:

图中有两条车道:
1、一条车道上的车以80Km/h前进
2、另一条车道上的车以30Km/h前进
在这一刻,你是黄色汽车,有两种选择前进
1、向左走,快速超过前面两辆车
2、在现在这条道上继续前进
让我们分析这两种选择。第一种选择你会立即超越前面的车,到达卡车的后面,然后以30Km/h的速度前进,寻找机会回到下面的车道上。所有之前在你后面的汽车会超过你。如果你的目标是在接下来比如10秒内前进最大的距离,当前选择是最佳的。第二种选择,你以当前速度前进,超过卡车然后超车,这取决于前面的道路情况。
这正是普通决策树和剪枝的区别。待约束条件的决策树不会看到前面的卡车,会残躯贪婪的方法向左变道。另一方面,如果我们使用剪枝方法,实际上我们向前观察了几步然后作出决定。
因此我们知道剪枝更好。但是如何在决策树中进行剪枝呢?想法很简单。
1、我们首先使决策树的的深度到一定程度大。
2、然后我们从底部开始,开始删除这样的一些节点,这些节点相对于父节点会返回负值。
3、假设一次分裂获得增益为-10,下一次分裂获得增益为20。简单的决策树会在第一步停止分裂。在剪枝方法中,我们会看到总增益是+10,因此保留两个叶节点(即进行两次分裂)
注意,sklearn的决策树分类器当前不支持剪枝。高级的库想xgboost具有剪枝功能实现。R中的rpart库提供剪枝功能,对R用户非常有用。

5、树模型比线性模型更好么?

“如果我可以使用逻辑回归解决分类问题,线性回归解决回归问题,为什么还要使用树?”我们中的许多人有这样的疑问,树也是一个非常有用的方法。
实际上,你可以使用任何算法。这取决于你要解决的问题类型。让我们看一些关键因素,帮助你决定使用哪种算法。
1、如果因变量和自变量的关系能用线性模型很好地近似表达,线性回归会优于树模型。
2、如果因变量和自变量的关系是高度非线性和非常复杂关系,树模型会优于经典回归方法。
3、如果你需要构建一个易于解释的模型,决策树模型总会比线性模型更好。决策树模型甚至比线性回归模型更容易解释。

6、在R和Python中使用决策树

对于R和Python用户,决策树实现非常容易。让那我们快速浏览一段代码,开始了解这个算法。为了便于使用,我共享了标准代码,你可以方便地替换成你的数据集和变量名,然后直接开始使用。
对于R用户,又多个可用的软件包来实现决策树,例如Ctree,rpart,tree等。
> library(rpart)
> x <- cbind(x_train,y_train)
# grow tree 
> fit <- rpart(y_train ~ ., data = x,method="class")
> summary(fit)
#Predict Output 
> predicted= predict(fit,x_test)
在以上代码中:
  y_train 表示因变量
  x_train 表示独立变量
  x 表示训练数据
对于Python用户代码如下:
#Import Library
#Import other necessary libraries like pandas, numpy...
from sklearn import tree
#Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset
# Create tree object 
model = tree.DecisionTreeClassifier(criterion='gini') # for classification, here you can change the algorithm as gini or entropy (information gain) by default it is gini  
# model = tree.DecisionTreeRegressor() for regression
# Train the model using the training sets and check score
model.fit(X, y)
model.score(X, y)
#Predict Output
predicted= model.predict(x_test)

7、基于树模型的集成方法有哪些?

“ensemble”单词的文字意义是群组的意思。Ensemble methods(集成方法)指使用一组具有预测能力的模型达到更好的准确度和模型稳定性。集成方法是已知的能最大限度提升树为基础的模型的方法。
像其他模型一样,基于树的模型也具有偏差和方差的问题。偏差表示一般情况下预测值区别于实际值的偏差程度。方差表示当相同数据集中的不同的样本在模型中的同一个点预测值的差异程度。
你建立一颗比较小的树,会获得一个具有低方差,高偏差结果。如何平衡偏差和方差之间的权衡?
通常,当你增加模型复杂度,你会看到由于模型的偏差降低,预测错误率会降低。当你持续提升模型复杂度,会导致模型过拟合,你的模型会产生高偏差。
好的模型应该在偏差和方差两者之间保持平衡。这就是所谓的偏差-方差权衡管理。集成学习是一种执行这种权衡分析的方法。

一些常用的集成方法包括:Bagging、Boosting和Stacking。在本教程中,我们重点介绍Bagging和Boosting的细节内容。

8、Bagging方法及工作原理

Bagging是一种用于降低偏差的方法,它使用在相同数据集合的不同子集上建模的多个分类器的分类结果作为最终预测结果。下面的图会使它更加清晰。

Bagging步骤如下:
1、创建多个数据集
抽样通过在原始数据上有放回地完成,形成新的数据集。
新的数据集可以是行采样,也可以是列采样得到,这在bagging模型中通过超参数控制。
考虑使用行采样和列采样能够是模型鲁棒性更好,防止过拟合。
2、 构建多个分类器
分类器是在每个数据集上创建的。
通常在每个数据集上进行建模和预测。
3、组合分类器
所有分类器通过平均值、中位数、值出现最多等方式进行组合得到分类结果,具体视情况而定。
组合后的值通常比单个模型更加健壮。
注意,这里建立的模型数量不是超参数。模型的个数越多总是会比较少的模型个数获得更好或同样号的预测结果。可以通过理论证明,在一定条件下,组合预测的方差会减少到原始方差的1/n(n是分类器个数)。
有各种各样的Bagging模型。随即森林是其中之一,我们接下来讨论它。

9、Random Forest模型及工作原理

随机森林(Random Forest)被认为是数据科学问题的灵丹妙药。一句玩笑话说,当你想不出任何算法(无论何时),请使用随即森林!
随即森林是一种通用的机器学习方法,能够解决分类和回归任务。它同时可以进行降维、处理缺失值、离群值和其他数据探索,并且效果相当好。它是一种集成学习方法,采用一组弱模型结合起来,组成一个强大的模型。

它是如何工作的?

在随机森林中,我们产生多颗树而不是像CART模型产生一棵树(查看CART和Random Foreset对比 part1和 part2)。根据属性对新的对象进行分类,每棵树给出一个分类,我们说这些树对该类进行投票。随即森林选择具有最多投票的类作为最终分类结果,对于回归问题,取不同树的输出结果平均值。

它的工作方式如下。每棵树种植和生长如下:
1、假设训练集中样本个数为N,这N个样本是随机选择的,但是有放回的。这个样本就是树生长用的训练数据集。
2、如果有M个输入变量,指定数字m
3、每棵树都成长到最大程度,没有剪枝操作。
4、通过组合多棵树的预测结果去预测新的数据(即多数投票处理分类问题,取平均值处理回归问题)。

要了解更多关于该算法的详细案例研究,请阅读这篇文章“ Introduction to Random forest – Simplified”

随机森林的优势

该算法可以解决分类和回归两种不同的问题,并且都能够有不错的预测结果。
随即森林最让我兴奋的一个地方是它可处理高维数据的能力。它可以处理成千上万维的输入变量,并确定最重要的哪些维度,因此它被视为一种降维方法。此外,该模型输出不同维度变量的重要性,这是一个非常方便的功能(在一些随机数据集上)。
它是一种有效的方法,可以用来估计数据丢失,当大量数据丢失时仍保持预测精度。
它能够处理数据集类别不均衡产生的错误。
上述能力可以扩展到未标记数据,进行无监督聚类,数据视图和离群检测。
随机森林采取有放回地随即采样,称为bootstrap采样。这里三分之一的数据不用来训练可以用来进行测试。这成为out of bag采样。这些out of bag采样的估计错误称为out of bag错误。研究out of bag错误估计,表明out of bag估计的精度和使用与训练集大小相同的测试集时是差不多的(即提高测试集大小到和训练集差不多,精度不怎么变化,说明模型健壮)。因此使用out-of-bag错误估计不需要专门保留一份测试集合(一般这份测试集合不用于训练,也不包含在采样的训练集中)。

随即森林的劣势

它确实擅长处理分类问题,但是不擅长处理回归问题,因为它不能给出精确的连续性预测。对于回归问题,它不能预测超出训练集范围的值。并且他们可能在噪声特别大的数据集上产生过拟合。
随即森林的感觉像一个黑盒子方法的统计模型--你很少需要控制模型在做什么,你最多可以尝试不同的参数和随即种子!

Python & R实现

随即森林在R和Python scikit-learn中均有实现。让我们看看在R和Python中加载随机模型的代码:
Python代码
#Import Library
from sklearn.ensemble import RandomForestClassifier #use RandomForestRegressor for regression problem
#Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset
# Create Random Forest object
model= RandomForestClassifier(n_estimators=1000)
# Train the model using the training sets and check score
model.fit(X, y)
#Predict Output
predicted= model.predict(x_test)
R代码
> library(randomForest)
> x <- cbind(x_train,y_train)
# Fitting model
> fit <- randomForest(Species ~ ., x,ntree=500)
> summary(fit)
#Predict Output 
> predicted= predict(fit,x_test)

10、GBM与XGboost哪个更强大?

定义:Boosting一词指将弱学习器转化为强学习器的一些算法。
让我们通过解决一个垃圾邮件识别分类问题详细理解这个定义。
你会如何分类电子邮件为垃圾邮件或不是?和其他人一样,我们最初的做法是使用以下标准来识别垃圾邮件和非垃圾邮件。
1、当邮件中只有一个图片文件(宣传图片),它是一个垃圾邮件。
2、当邮件中只有连接,他是一个垃圾邮件。
3、当邮件正文包含如“你赢得了XXX美元的奖金”这样的句子,它是一个垃圾邮件。
4、来自我们官网域名Analyticsvidha.com的邮件,不是垃圾邮件。
5、来自已知来源的邮件,不是垃圾邮件。
以上,我们定义了多个规则分类垃圾邮件和非垃圾邮件。但是,你认为这些独立规则足够强大能够成功分类垃圾和非垃圾邮件么?不。
单独地,这些规则没有强大到能够分类一个邮件是垃圾邮件或非垃圾邮件,因此这些规则被称为 弱学习器
要把若学习器转化为强学习器,我们结合每个弱学习器的预测结果,使用如下方法:
  • 使用平均或加权平均
  • 考虑具有较高投票的预测
例如:上面,我们定义了5个弱学习器,这5个当中3个预测结果为垃圾邮件,2个预测结果为非垃圾邮件。在这种情况下,默认情况下,我们会认为一个该邮件是垃圾邮件,因为我们对垃圾邮件的投票数量更多。

它是如何工作的?

现在我们知道,提升方法(boosting)组合弱学习器(基学习器)形成一个强规则。立刻出现在你脑海中的一个问题是,“提升方法如何发现弱规则的?”
为了找到弱规则,我们采用不同分布的基学习算法。每次使用基学习算法,它产生一个新的弱预测规则。这是一个迭代的过程。经过许多次迭代,提升算法将这些弱规则组合成一个强预测规则。
这里有另一个或许困扰你的问题是,“我们如何在每一轮选择不同的分布?”
选择正确的分布,这里有以下步骤:
第一步:基学习器获取所有数据分布,对每个实例赋予相等的权值。
第二步:如果有第一个基学习器产生的预测错误,我们会更加关注具有预测错误的那些实例。然后我们运用下一个基学习算法。
第三步:迭代第二步,直到基达到基学习器的极限或更高的精度。
最后,它组合弱学习器的输出,产生一个强学习器,最终提升模型的预测能力。提升方法更加关注被误分类的那些样本,或者被之前的弱分类器分类误差率较高的样本。
有许多提升算法能够是模型精度得到更多的提升。在本教程中,我们将了解两种最常使用的算法,即GBM(梯度提升)和XGboost。

11. 哪个更强大?GBM还是XGboost?

我一直很钦佩xgboost算法的提升能力。有时,我发现它提供比GBM更好的结果,但是有时候你会发现收效甚微。当我探索更多关于性能和他高准确率的科学背后,我发现XGboost相对于GBM有很多有点。

1、正则化(Regularization):

  • 标准GBM实现没有像XGBoost实现正则化,因此它有助于防止过拟合。
  • 实际上,XGBoost也被称为正则化的提升技术。

2、并行处理(Parallel Processing):

  • XGBoost实现并行处理,计算速度相比GBM更快
  • 但是等一下,我们知道提升方法是连续的过程,它如何能够被并行化?我们知道,每棵树只能在前面一棵树建立完成后建立,那么什么阻止我们使树建模利用所有核心?我希望你能够查看我发现的内容,点击这里进一步研究

3、灵活性高(High Flexibility)

  • XGBoost允许用户定义自定义的优化目标和评价标准。
  • 这给模型增加了一个全新的维度,使得我们可以无限制地做我们想做的任何事情。

4、处理缺失值(Handling Missing Values)

  • XGBoost有一个内置的方法处理缺失值。
  • 用户需要提供 和其他观测值不一样的值,传递这个值作为参数(作为默认的缺失值,默认是NAN)。XGBoost在每个节点上遇到缺失值的时候尝试不同的思路,学习未来遇到缺失值时执行哪条路径。

5、树剪枝(Tree Pruning)

  • 在分裂过程中,当GBM遇到负的损失值会停止分裂当前节点。因此它是一个贪心算法。
  • XGBoost则是继续分裂直到设置的最大树深度,然后开始剪枝回退,移除没有正增益的分裂节点。
  • XGBoost的另一个优势是有时候分列产生负增益比如-2,或许随后会产生+10的正增益。GBM会在遇到-2增益时直接停止。但是XGBoost则会继续分裂,它最终或得+8的增益。

6、内置交叉验证(Built-in Cross-Validation)

  • XGBoost允许用户在提升过程每次迭代过程运行交叉验证,因此很容易在一次运行过程中或得最有数目的提升迭代次数。
  • 这不像GBM必须运行网格搜索(Grid-Search),只有有限的值可以测试。

7、在已有模型基础上继续训练

  • 用户可以从最后一次迭代之前的运行结果继续进行模型训练。这在某些应用中具有显著优势。
  • sklearn中的GBM实现也具有这个特点,因此在这点上他们是差不多的。

12、在R和Python中使用GBM

在我们开始工作之前,让我们快速了解这个算法的重要参数和工作流程。这对于R和Python用户来说非常有用。下面是两种GBM算法的伪代码:
1. Initialize the outcome
2. Iterate from 1 to total number of trees
  2.1 Update the weights for targets based on previous run (higher for the ones mis-classified)
  2.2 Fit the model on selected subsample of data
  2.3 Make predictions on the full set of observations
  2.4 Update the output with current results taking into account the learning rate
3. Return the final output.
这是GBM工作过程的一个及其简化的解释。但是可以帮助每个初学者理解该算法。
让我们考虑python中提升GBM模型表现的重要参数。

1、学习率(learning_rate)

  • 这决定了每棵树对最终结果的影响(上述算法步骤2.4),GBM开始初始化树,并且利用每棵树的输出结果进行更新。学习参数控制在估计中变化幅度。
  • 较低的值通常是优先选择的,因为它使得模型面对具体特征时仍然保持健壮性,因此据i有很好的泛化能力。
  • 较低的值需要较大数量的树对所有关系进行建模,因此计算代价比较高

2、树的个数(n_estimators)

  • 要建模的树序列的个数(上述算法步骤2)。
  • 虽然GBM在树的数量比较多时比较强壮,它在某些点仍然会过拟合。因此这应该通过交叉验证提交特定的学习率。

3、样本采样率(subsample)

  • 每棵树选择的样本比例。选择是通过随机抽样完成。
  • 值略小于1能够降低偏差,使得模型更强壮。
  • 通常0.8左右工作良好,但可以进一步微调。
除此之外,还有一些影响整体功能的其他参数。

1、loss

  • 它指损失函数,每次分裂过程中需要最小化的函数。
  • 对于分类和回归问题,它可以有不同的值。通常默认值就可以工作良好。当你理解它对模型的影响时也可以选择其他参数值。

2、init

  • 这会影响输出的初始化。
  • 当我们使用另外一个模型作为GBM初始估计的时候可以使用该参数。

3、random_state

  • 随机种子数,确保每次产生相同的随机数。
  • 这对于调整参数非常重要。如果不固定随即数,那么对于相同的参数我们会得到不同的结果,对比模型会变得非常困难。
  • 它可能会导致过拟合到特定的随机抽取的样本,我们可以尝试使用不同的随机样本,这样计算昂贵,一般不这么用。

4、verbose

  • 当模型训练时,打印的输出类型。不同的取值可以是:0:没有输出(默认),1:一定间隔地输出生成树,>1:输出所有的生成树

5、warm_start

  • 这个参数有一个有趣的应用,如果使用恰当会有很大的帮助。
  • 使用这个参数,我们可以基于之前的模型继续训练。它可以节省大量时间,高级应用场景中应该探索这个选项。

6、presort

  • 选择是否对数据重排序,提升分裂速度。
  • 它默认自动选择,但是如果需要可以改变。
我知道这是一个很长的参数列表,但我已经简化后放到excel中,你可以从 GItHub仓库中下载。
对于R用户,使用caret库,有三个主要的参数需要调节:
1、n.tree 指迭代次数,即成长为树林的树的个数。
2、iteration.depth 它决定了树的复杂度。即对一个数执行分裂的最大次数。
3、shrinkage 它指学习率,类似python中的learning_rate。
4、n.minobsinnode 它指对一个节点进行分裂时需要的最小样本个数。

GBM in R (with cross validation)

我已经分享了R和Python的标准代码。在这里,你需要修改独立变量的值和数据集的名称。考虑R中GBM的易用性,你可以很容易使用它进行交叉验证和网格搜索。
> library(caret)

> fitControl <- trainControl(method = "cv",
                           number = 10, #5folds)

> tune_Grid <-  expand.grid(interaction.depth = 2,
                            n.trees = 500,
                            shrinkage = 0.1,
                            n.minobsinnode = 10)

> set.seed(825)
> fit <- train(y_train ~ ., data = train,
                 method = "gbm",
                 trControl = fitControl,
                 verbose = FALSE,
                 tuneGrid = gbmGrid)

> predicted= predict(fit,test,type= "prob")[,2] 
GBM in Python
#import libraries

from sklearn.ensemble import GradientBoostingClassifier #For Classification
from sklearn.ensemble import GradientBoostingRegressor #For Regression

#use GBM function

clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0, max_depth=1)
clf.fit(X_train, y_train)

13、在Python和R中使用XGBoost

XGBoost (eXtreme Gradient Boosting)是一种高级的梯度提升算法。他的特点是可以并行计算,使得它至少比现有的梯度提升实现快10倍以上。它支持各种目标函数,包括回归,分类和排序。
R教程: 对于R用户,这是一个对XGBoost比较全面的教程,它通过R代码解释各个参数, 查看教程。
Python教程: 对于Python用户,这是对XGBoost的全面介绍教程,可以让你很好地开始。 查看教程。

14、哪里进行练习?

实践是掌握任何概念的唯一和真正方法。因此你需要开始实践,如果你希望掌握这些算法。
在这里,你已经基于树模型的重要知识,以及这些实际实现。是时候开始研究它们了。这里有一些开放的实践问题,你可以参与并且参与排名。
对于回归问题: Big Mart Sales Prediction
对于分类问题: Load Prediction

结束语

基于树的算法对每个数据科学家来说都十分重要,需要去学习。实际上,树模型被称为是在整个机器学习算法领域中最出色的模型。在本教程中,我们学习了GBM和XGBoost,到这里,我们走到了本教程的结尾。
我们从头讨论了基于树的建模。我们学习了决策树的重要性,以及这些简单概念是在提升算法中如何被使用。为了更好地理解,我建议你继续实际地实践这些算法。同时注意和提升算法相关的参数。我希望该教程能够使得你对基于树模型的知识更加丰富完整。
你觉得该教程有用么?如果你有相关经验,你在树模型中使用的最好的技巧是什么,欢迎随时分享你的技巧、建议和意见。

你可能感兴趣的:(Machine,Learning,gbdt)