大数据安全

关于基于树的建模的完整教程(从R&Python)

2016-11-15  本文已影响900人  珞珈村下山

翻译自analyticsvidhya

基于树的学习算法被认为是最好的和最常用的监督学习(supervised learning)方法之一。基于树的方法赋予预测模型高精度,稳定性和易于解释的能力。 与线性模型不同,它们非常好地映射非线性关系。 它们适应于解决手头的任何问题(分类或回归)。
决策树,随机森林,梯度提升等方法被广泛用于各种数据科学问题。 因此,对于每个分析师(新手也是一样)来说,重要的是学习这些算法并将其用于建模。
本教程旨在帮助初学者从头开始学习基于树的建模。 成功完成本教程之后,人们期望熟练使用基于树的算法和构建预测模型。
注意:本教程不需要机器学习的先验知识。 然而,R或Python的基本知识将是有帮助的。 在开始本教程前你可以从头开始学习Python或者R语言。

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

决策树是一种主要用于分类问题的监督学习算法(具有预先定义的目标变量)。 它适用于分类变量和连续型的输入输出变量。 在这种技术中,我们基于输入变量中最重要的分割器/微分器将总体或样本分成两个或更多个同质集合(或子集群)。

dt.png

例子:

假设我们有30个学生的样本,有三个变量:性别(boy/girl),班级(IX / X)和身高(5到6英尺)。 30名孩子中间有15个在业余时间打板球。 现在,我想创建一个模型来预测谁将在业余时间玩板球? 在这个问题中,我们需要根据所有三个中最重要的输入变量来区分在休闲时间玩板球的学生。
这是决策树最有用的地方,它将基于三个变量的所有值划分学生,并识别变量,这创建了最好的同质学生集合(彼此是异质的)。 在下面的截图中,您可以看到变量Gender与其他两个变量相比能够最好的识别同类集。

Test-1024x249.png

如上所述,决策树识别最重要的变量,它是给出最佳同质集合的值。 现在的问题是,它如何识别变量和分裂? 为此,决策树使用了各种算法,我们将在下一节中讨论。

决策树的类型

决策树的类型是由我们所拥有的目标变量的类型决定的。它可以有两种类型:

与决策树相关的重要术语(important terminology)

让我们来看看决策树使用的基本术语:

Decision_Tree_2.png

以上这些都是通常用于决策树的术语。我们知道每个算法都有优缺点,下面是我们应该知道的重要因素。

优点
缺点

2.回归树和分类树

我们都知道终端节点(或叶)位于决策树的底部。 这意味着决策树通常被倒置地绘制,使得叶子是底部和根部是顶部(如下所示)。

111.png

两个树的工作模式几乎相似,让我们看看分类树和回归树之间的主要差异和相似性:

  1. 当因变量(dependent variables)是连续变量时,使用回归树。当因变量是分类变量时,使用分类树。
  2. 在回归树的情况下,由训练数据中的终端节点获得的值是落在该区域中的观测值的平均响应。因此,如果一个不可见的数据观测值属于该区域,我们将用平均值进行预测。
  3. 在分类树的情况下,终端节点在训练数据中获得的值(类)是落在该区域中的众数。因此,如果一个不可见的数据观测值落在该区域,我们将使用众数值进行预测。
  4. 这两棵树将预测变量空间(自变量)划分为不同的和非重叠的区域。为了简单起见,您可以将这些区域视为高维盒子或箱子。
  5. 两个树都遵循称为递归二进制分裂的自上而下的贪婪方法。我们将其称为“自上而下”,因为当所有观察结果在单个区域中可用时,它从树的顶部开始,并且连续地将预测器空间分割成树中的两个新分支。它被称为“贪婪”,因为,算法仅仅关心(寻找最佳可用变量)关于当前的分裂,而不是关于未来分裂(而这将导致更好的树)。
  6. 该分裂过程继续,直到达到用户定义的停止标准。例如:一旦每个节点的观测数量小于50,我们就可以告诉算法停止。
  7. 在这两种情况下,分裂过程导致完全生长的树,直到达到停止标准。但是,完全生长的树可能过度拟合数据,导致未知数据的准确性差。这带来了“修剪”。修剪是使用滑轮过度配合的技术之一。我们将在下一节中详细了解它。

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

树的分裂策略严重影响树的准确性。分类树和回归树的决策标准是不同的。
决策树使用多个算法来决定将一个节点分裂成两个或更多个子节点。子节点的创建增加了所得到的子节点的同质性。 换句话说,我们可以说,节点的纯度相对于目标变量增加。 决策树分裂所有可用变量上的节点,然后选择导致最一致子节点的分裂。
算法选择也基于目标变量的类型。 让我们来看看决策树中最常用的四种算法:

吉尼指数(Gini Index)

吉尼指数指出,如果我们从一个群体中随机选择两个项目,而且它们必须是相同的类别,如果群体是单一的,那么概率为1。

计算分裂的Gini指数的步骤:
例子

参考上面使用的示例,其中我们想基于目标变量(玩或不玩板球)来划分学生。 在下面的快照中,我们使用两个输入变量Gender和Class来拆分总体。 现在,我想确定哪个拆分使用Gini指数能够生成更均匀的子节点。

Decision_Tree_Algorithm1.png
基于性别分裂:
相似地,基于年级的分裂:

在上面,您可以看到,“Gender”的Gini分数高于“Class”的分数,因此,节点拆分将在“Gender”上进行。

卡方(Chi-Square)

它是一种计算子节点和父节点之间的差异的统计显著性的算法。 我们通过目标变量的观测频率和预期频率之间的标准差的平方和来测量。

计算分裂的卡方值的步骤:
例子

我们依然使用上面计算吉尼指数的例子
基于性别的分裂:

Decision_Tree_Chi_Square1.png

基于年级的分裂
步骤类似于上面基于性别的分类,详见下表

Decision_Tree_Chi_Square_2.png

上面,你可以看到,卡方值也识别出性别分裂比类别更显著。

信息增益(Information Gain)

观察下面的图像,并指出哪个节点可以很容易地描述。 我相信,你的答案是C,因为它需要较少的信息,因为所有的值都是类似的。 另一方面,B需要更多的信息来描述它,A需要最大的信息。 换句话说,我们可以说C是一个纯节点,B是不纯,A是更不纯。

Information_Gain_Decision_Tree2.png

现在,我们可以得出一个结论,一个样本拥有越少的不纯节点,描述这个样本所需的信息越少。而更多的不纯节点则需要更多的信息来描述。 信息论(Information Theory)采用“熵(Entropy)”来衡量一个系统的紊乱程度。如果样本完全均匀,则熵为零,如果样本是等分的(50%-50%),则熵为1。
熵的计算公式:

$$Entropy = p\log_2p-q\log_2q$$

这里p和q分别是该节点的成功和失败的概率。 熵也与分类目标变量一起使用。 它选择与父节点和其他分裂相比具有最低熵的分裂。 熵越小,它越好。
计算分割的熵的步骤:

例子

让我们使用这个方法来识别学生示例的最佳分裂。

上面,你可以看到,在性别上分割的熵是最低的,所以树将在性别上分裂。 我们可以从熵中获取信息增益为1-熵。

方差缩减(Reduction in Variance)

到目前为止,我们已经讨论了分类目标变量的算法。 方差的减少是用于连续目标变量(回归问题)的算法。 该算法使用标准方差公式选择最佳分割。 选择具有较低方差的分割作为分割总体的标准:

方差公式

$$
s2={\frac1n}\sum_{i=1}n(x_i-\overline{x})^2
$$

计算方差的步骤:

例子

我们把打板球赋值为1,不打板球赋值为0。 现在按照步骤确定正确的分割:

上面,您可以看到,与父节点相比,性别拆分具有更低的方差,因此拆分将在Gender变量上进行。
在此之前,我们了解了决策树的基础知识,以及决策过程涉及在构建树模型中选择最佳分割。 正如我所说,决策树可以应用于回归和分类问题。 让我们来详细了解这些方面。

4.树模型的关键参数是什么?我们如何避免过度拟合的决策树?

过度拟合是决策树建模时面临的关键挑战之一。 如果没有决策树的限制集,它将给你100%的训练集精度,因为在最坏的情况下,它将最终为每个观察生成1个叶子节点。 因此,防止过拟合在对决策树建模时是关键的,并且可以以两种方式来完成:

让我们简要讨论这两个。

在树的大小上设置约束

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

tree-infographic.png

下面进一步解释用于定义树的参数。 以下描述的参数与工具无关。 重要的是要了解树模型中使用的参数的作用。 这些参数在R&Python中可用。

1. 节点分割的最小样本(Minimum samples for a node split)
2. 终端节点(叶)的最小样本(Minimum samples for a terminal node (leaf))
3. 树的最大深度(垂直深度)(Maximum depth of tree (vertical depth))
4. 终端节点的最大数量(Maximum number of terminal nodes)
5. 要考虑拆分的最大特征数(Maximum features to consider for split)
树的修剪

如前所述,设置约束的技术是贪婪方法。 换句话说,它将立即检查最佳分离并向前移动,直到达到指定的停止条件之一。 让我们考虑以下情况当你开车:

graphic-1024x317.png

这里2个车道:

在这个时刻,你是黄色的车,你有两个选择:

让我们分析这些选择。 在前一种选择中,您将立即超车,然后到达卡车后面,以30公里/小时的速度开始移动,寻找机会向右移动。 原来在你身后的所有车辆同时向前移动。 这将是最佳的选择,如果你的目标是在下一个10秒覆盖最大的距离。 在后面一个 选择中,你以相同的速度前行,赶上卡车,然后超过,可能取决于前面的情况。 你好贪心!
这正是正常决策树和修剪之间的区别。具有约束的决策树将不会看到前面的卡车,并采取贪婪的方法左转。 另一方面,如果我们使用修剪,我们实际上会看前面几步,并做出选择。
所以我们知道修剪是更好的。 但是如何在决策树中实现它呢? 这个想法很简单。

注意sklearn的决策树分类器目前不支持修剪。 高级包像xgboost在它们的功能中已经采用了树修剪。 但是R中rpart包,提供了一个修剪的函数。 对于R用户自然是极好的!

5. 基于树的模型是否比线性模型好?

“如果我可以对分类问题使用逻辑回归和对回归问题使用线性回归,为什么要使用树”? 我们许多人都有这个问题。 而且,这也是一个有效的问题。
实际上,你可以使用任何算法。 它取决于你解决的问题的类型。 让我们来看看一些关键因素,它们将帮助你决定使用哪种算法:

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)

在上面的代码中:

对于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 methods)?

词语“ensemble”的文学意义是群体。 集成方法涉及预测模型组,以实现更好的准确性和模型稳定性。 已知集成方法对基于树的模型赋予了极大的提升。
像所有其他模型一样,基于树的模型也遭受偏差和方差的影响。 偏差意味着“预测值与实际值存在多大程度的差异”。方差意味着,如果不同的样本是从同一个总体中获取的,模型的预测值与总体存在多大差异。
你建立一个小树,你会得到一个低方差和高偏差的模型。 你如何设法找到偏差和方差之间的折衷方案?
通常,当您增加模型的复杂性时,由于模型中的偏差较小,您将看到预测误差的减少。 随着你继续让你的模型更复杂,你最终会过度拟合你的模型,你的模型将开始遭受高方差。
一个冠军模型应该保持这两种类型的错误之间的平衡。 这被称为偏差方差误差的权衡管理。 集成学习是执行这种权衡分析的一种方式。

model_complexity.png

一些常用的集成方法包括:装袋,拉动和堆积(Bagging, Boosting and Stacking)。 在本教程中,我们将详细介绍Bagging和Boosting。

8. 什么是Bagging? 它是如何工作的?

Bagging是一种用于通过组合对相同数据集的不同子样本建模的多个分类器的结果来减少我们的预测的方差的技术。 下图将使其更清楚:

bagging.png

装袋中的步骤是:

  1. 创建多个DataSet:
  1. 构建多个分类器:
  1. 组合分类器:

注意,这里建立的模型数量不是超参数。 较高数量的模型总是更好,或者可以给出与较低数字类似的性能。 在理论上可以表明,在某些假设下,组合预测的方差减小到原始方差的1 / n(n:分类器的数量)。
装袋模型有各种实现。 随机森林是其中之一,我们将在下面讨论它。

9. 什么是随机森林? 它是如何工作的?

随机森林被认为是所有数据科学问题的灵丹妙药。 在一个有趣的信条,当你想不出任何算法(不论任何情况),使用随机森林!
随机森林是一种多功能机器学习方法,能够执行回归和分类任务。 它还采用降维方法,处理缺失值,异常值和数据探索的其他必要步骤,并且做得相当不错。 它是一种集成学习方法,一组弱模型组合形成一个强大的模型。

它是如何工作的

在随机森林中,我们在CART模型中生成多棵树,而不是单棵树(参见CART和Random Forest之间的比较,第1部分第2部分)。 为了基于属性对新对象进行分类,每个树给出一个分类,并且我们说给该树的“投票”。 森林选择具有最多票数(在森林中的所有树上)的分类,并且在回归的情况下,它取不同树的输出的平均值。
它以以下方式工作。 每棵树种植和种植如下:

all-data-set-850x751.jpg

要了解更多关于此算法使用案例研究,请阅读这篇文章随机森林简介 - 简化

随机森林的优点
Variable_Important.png
随机森林的缺点
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 Code

> 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.什么是Boosting? 它是如何工作的?

定义:术语“Boosting”是指将弱学习者转化为强大学习者的算法家族。

让我们通过解决垃圾邮件识别问题来详细了解这个定义:
您如何将电子邮件分类为垃圾邮件? 和其他人一样,我们的初始方法是使用以下标准来识别“垃圾邮件”和“非垃圾邮件”电子邮件。 如果:

以上,我们定义了多个规则,将电子邮件分为“垃圾邮件”或“非垃圾邮件”。 但是,你认为这些规则是否足够强大以成功分类电子邮件? 没有。

个别地,这些规则不足以将电子邮件分类为“垃圾邮件”或“非垃圾邮件”。 因此,这些规则被称为弱学习者。
为了将弱学习者转换为强学习者,我们将使用以下方法来组合每个弱学习者的预测:

例如:上面,我们定义了5个弱学习者。 在这5个中,3个被表决为“垃圾邮件”,2个被表决为“不是垃圾邮件”。 在这种情况下,默认情况下,我们会将电子邮件视为垃圾邮件,因为我们对“垃圾邮件”投票较高(3)。

它是如何工作的?

现在我们知道,"Boosting"结合弱学习者和基础学习者形成一个强大的规则。 在你心目中应该浮现的一个直接的问题是,“Boosting是如何识别弱规则的?"

为了找到弱规则,我们应用具有不同分布的基础学习(ML)算法。每应用一次基础学习算法,它就会生成新的弱预测规则。 这是一个迭代过程。 在许多迭代之后,增强算法将这些弱规则组合成单个强预测规则。

另一个可能困扰你的问题是,"我们如何为每轮选择不同的分布?"
为了选择正确的分布,请执行以下步骤:

最后,它结合了弱学习者的输出,并创建了一个强大的学习者,最终提高了模型的预测能力。 Boosting通过前面的弱规则更加关注错误分类或具有更高错误的示例。
有许多增强算法给予模型的精度额外的提升。 在本教程中,我们将了解两种最常用的算法,即Gradient Boosting(GBM)和XGboost。

11. 哪个更强大:GBM或Xgboost?

我一直很欣赏的xgboost算法增强能力。有时,我发现它比起GBM实现了较好的效果,但有时,你可能会发现,收益只是微不足道的。 当我探索更多关于它的性能和科学背后的高精确度后,我发现了Xgboost相比GBM的更多优点:

  1. 正则化:
  1. 并行处理:
  1. 高灵活性
  1. 处理缺少的值
  1. 修剪树:
  1. 内置交叉验证
  1. 在现有模型上继续运行

12. 在R和Python中使用GBM

在我们开始工作之前,让我们快速了解这个算法的重要参数和工作原理。 这将有助于R和Python用户。 下面是GBM算法的2个类的总体伪代码:

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
  1. n_estimators
  1. subsample

除此之外,还有一些影响整体功能的杂项参数:

  1. loss
  1. init
  1. random_state
  1. verbose
  1. warm_start
  1. presort

我知道它的一个长列表的参数,但我已经简化了它在一个excel文件,你可以从这个GitHub存储库下载。

对于R用户,使用caret包,有3个主要调整参数:

R中的GBM(带交叉验证)

我已经共享了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. 在R和Python中使用XGBoost

XGBoost(eXtreme Gradient Boosting)是梯度提升算法的高级实现。 它的功能是实现并行计算,使其至少比现有的梯度提升实现快10倍。 它支持多种目标函数,包括回归,分类和排名。

R教程:对于R用户,这是一个完整的教程XGboost,解释参数和代码在R.检查教程

Python教程:对于Python用户,这是一个关于XGBoost的综合教程,很好地帮助您入门。 检查教程

14.在哪里练习?

实践是掌握任何概念的一个真正的方法。 因此,如果你想掌握这些算法,你需要开始练习。

到这里,你已经获得了有关树基模型的重要知识以及这些实际实现。 现在是时候开始工作。 这里是开放的练习问题,你可以参加和检查您的排行榜上的实时排名:

回归:大市场销售预测

分类:贷款预测

结束注释

基于树的算法对于每个数据科学家都很重要。 事实上,已知树模型在整个机器学习算法族中提供最好的模型性能。 在本教程中,我们学会了直到GBM和XGBoost。 有了这个,我们来到本教程的结尾。

我们讨论了从头开始的基于树的建模。 我们学习了决策树的重要性,以及如何使用这种简单化的概念来提升算法。 为了更好地理解,我建议你继续实践这些算法。 此外,请记住与提升算法相关的参数。 我希望这个教程将丰富你有关树基建模的完整知识。

您觉得本教程很有用吗? 如果你有经验,你使用树的模型最好的技巧是什么? 请随时在下面的评论部分分享您的技巧,建议和意见。

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

上一篇下一篇

猜你喜欢

热点阅读