基于树模型的学习算法是最受欢迎的有监督学习方法之一,如决策树模型、随机森林、梯度提升树等算法,树模型能够使预测模型的精度更高、性能更稳定,模型结构也更方便解释和分析,对数据分析者来说学习如何在自己的模型中使用这些算法是很重要的。本案例主要是帮助数据分析初学者从零学习树模型,读者在学习完本案例后能够熟练的运用树模型以及构建预测模型。
决策树是一种主要用于解决分类问题(具有预定义的目标变量)的监督学习算法。决策树适用于分类变量和连续变量,我们根据输入变量中最重要的区分器(即变量),将样本分成两个或多个同构集合(或子类)。
举例:
假设我们有30个学生的样本,有三个变量:性别(男孩/女孩),班级(IX/X)和身高(5~6英尺)。这30个人中有15个人在业余时间打板球。现在,我们想创建一个模型来预测谁将在业余时间玩板球?这个问题中,我们需要根据三个特别显著的输入变量,区分出在业余时间玩板球的学生。
这就是决策树的作用,他能够通过三个变量值来区分学生,创建最好的同构集合(彼此是异质的)。如图所示,我们可以看到性别变量相较于其他两个变量选出的同构集合最好。
综上所述,决策树能够识别出最重要的变量及变量值,并给出最优的同构集合。现在的问题是,他是如何识别变量然后进行分类的?在识别变量和判断分类时,决策树使用了各种算法,我们将在下面的章节中讨论。
决策树的类型取决于目标变量的类型。可以分为两种:
举例:
假设我们要预测客户是否会向保险公司支付续保保费(是/否)。我们知道客户的收入是一个重要的变量,但保险公司没有所有客户的收入明细。我们知道这是一个重要的变量,然后建立一个决策树,根据职业、产品和各种其他变量来预测客户的收入。在这种情况下,我们预测的是连续变量的值。
决策树所使用的基本术语:
以上是常用于决策树的术语。众所周知,每一种算法都有优点和缺点,下面介绍决策树的优缺点。
优点:
缺点:
我们都知道,终端节点(或叶子)位于决策树的底部。这意味着决策树通常被倒置,使得叶子是底部而根是顶部(如下图所示)。
回归树与分类树的工作方式相似,下面看看两者之间主要的差异性和相似性:
分裂会严重影响决策树的准确性,分类树和回归树的决策标准有所不同。
决策树使用多个算法来决定在两个或多个子节点中对某一个节点进行分裂,子节点的创建增加了子节点间的同质性。决策树在所有可用的变量上分裂节点,然后选择使结果最均匀的子节点进行分裂。
算法的选择基于目标变量的类型,下面是决策树中最常用的四种算法:
基尼指数指出,如果分类中同质性很高,那么我们从分类中随机选择两个元素,他们肯定是相同的类别,并且概率为1。
使用基尼系数进行分裂的计算步骤:
举例:
参照上面的例子,我们基于目标变量(或不玩板球)区分学生。在下图中,我们使用性别和班级做为输入变量。然后使用基尼系数确定哪些分裂产生了更均匀的子节点。
在性别属性上分裂:
在班级属性上分裂:
可以看出,按性别分裂的基尼系数高于按班级分裂。因此,节点分裂将发生在性别属性上。
这是一种计算子节点和父节点间差异的统计学算法。计算方法是求目标变量观察频率和预期频率之间的标准差之和。
使用卡方计算分裂的步骤:
举例:
使用卡方来计算上面的例子。
在性别属性上分裂:
在班级属性上分裂:
通过类似按性别分裂的计算步骤,得到下表。
由此可以看出,卡方计算方法也认为按性别分裂比按班级分裂更有效。
看看下面的图片,想想我们可以很容易地描述出来哪个节点。我想你的答案肯定是C,因为所有的值都是相似的,需要的描述的信息最少。而B需要更多的信息来描述,A则需要最多的信息。可以说,C是纯度最高的节点集合,B是纯度不太高的集合,A是纯度最低的集合。
现在,我们可以得出这样的结论:纯度较高的节点只需要很少的信息来描述,反之则需要更多的信息来描述。信息论中用来衡量一个系统混乱程度的理论被称为熵。如果样本是完全同构的,那么熵是零,并且如果样本是均分的,则熵为1。
熵的计算公式:$Entropy=-p\log_2{p}-q\log_2{q}$。
这里的$p$和$q$分别为节点的成功和失败概率。熵也用于分类目标变量。选择相比父节点和其他节点分裂最低的熵。熵值越小越好。
通过熵进行分裂的计算步骤:
举例:
接下来我们使用这个方法对学生案例进行最佳分裂。
1.计算父节点的熵:$$Entropy for parent node = -(15/30)\log_2(15/30)–(15/30)\log_2(15/30)=1$$ 这里1表明是纯度较低的节点。
2.计算女性节点的熵:$$Entropy for Female node = -(2/10)\log_2(2/10)–(8/10)\log_2(8/10)=0.72$$ 男性节点的熵:$$Entropy for male node=-(13/20)\log_2(13/20)–(7/20)\log_2(7/20)=0.93$$
3.计算性别分裂的熵:$$Entropy for split Gender = Weighted entropy of sub-nodes = (10/30)*0.72 + (20/30)*0.93 = 0.86$$
4.班级IX节点的熵:$$Entropy for Class IX node=-(6/14)\log_2(6/14)–(8/14)\log_2(8/14) = 0.99$$ X班级的熵:$$Entropy for Class X node=-(9/16)\log_2(9/16)–(7/16)\log_2(7/16) = 0.99$$
5.计算班级分裂的熵:$$Entropy for split Class=(14/30)*0.99 +(16/30)*0.99 = 0.99$$
从上可以看到,性别分裂的熵是最低的,所以树会在性别属性上进行分裂。我们可以获得信息增益为$1- Entropy$。
现在,我们已经讨论了分类目标变量的算法。方差减少是一种用于连续目标变量(回归问题)的算法。该算法通过计算方差的标准公式来选择最佳分裂,选择具有较低方差的属性作为分裂准则。
$\overline{X}$表示平均值,$X$表示实际值,$n$表示变量个数。
方差的计算步骤:
举例:
我们为“玩板球”分配数值1,为“不打板球”分配数值0。现在按照步骤来识别分裂。
1.根节点的方差,平均值为$(15*1 + 15*0)/30 = 0.5$,我们有15个0和15个1,那么方差为:
$((1-0.5)^2+(1-0.5)^2+…15 times+(0-0.5)^2+(0-0.5)^2+…15 times) / 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$。
从上面的计算可以看到性别分裂方差比父节点低,所以分裂选择在性别属性上。
到这里,我们了解了基本的决策树和如何选择最好的分裂,建立树模型的决策过程。决策树可以应用在回归和分类问题上,下面我们详细了解这些方面。
使用决策树建模时,过拟合是一个关键挑战。如果一个决策树没有极限集,那么训练集准确度为100%。因此,决策树建模的关键是防止过拟合,可以从2个方面来进行:
接下来详细介绍这两部分。
可以通过使用定义树的各种参数来完成。首先,我们看看决策树的一般结构:
下面进一步解释用于定义树的参数,与描述参数的工具无关。了解树建模中参数的作用很重要,这些参数在R和Python中均可以使用。
(1).节点分裂的最小样本
(2).终端节点(叶子节点)的最小样本
min_samples_split
的方法防止过拟合。(3).树的最大深度(垂直深度)
(4).终端节点的最大数目
max_depth
的定义,由于创建二叉树,深度为$n$的数会产生最大的$2×N$个叶子节点。(5).分裂的最大特征
正如前面所讨论的,设置约束是种贪婪法。换言之,他能够及时检查最佳分裂并向前移动直到达到指定的停止条件之一。我们需要考虑以下情况:
有2个车道:
在这一刻,假设你是黄色车,你有2种选择:
让我们分析一下这些选择。在前一个选择中,你会立即超过前面的车,到达卡车后面,开始移动30公里/小时,寻找机会回到右边。在你身后的所有汽车都在前进。如果你的目标是在接下来的10秒最大限度的拉开距离,这将是最佳选择。在第二个选择中,你以同样的速度行驶,与卡车相遇,能否超车取决于后来的情况。贪婪的你!
普通决策树和剪枝的区别:带约束的决策树不会看到前方的卡车,而是采取贪婪的方法向左拐。 另一方面,如果我们使用剪枝,我们只要很少的步骤就能做出选择。
所以我们知道修剪更好。但如何在决策树中实现呢?这个想法很简单。
注意,Sklearn中的决策树分类器目前不支持剪枝,而XGBoost中支持进行剪枝。
“如果我可以使用逻辑回归来解决分类问题,使用线性回归来解决回归问题,还为什么需要使用树模型?”我们很多人都有这个问题。
实际上,您可以使用任何算法。这取决于您要解决的问题类型。让我们来看一些关键因素,他们将帮助您决定使用哪种算法:
对于Python用户来说,决策树是很容易实现的。让我们快速地查看一组代码,方便您开始使用这个算法。我们已经共享了标准代码,您只需要替换自己的数据集名称和变量即可开始。
在下面代码中,X代表训练数据集:
# 导入库文件
from sklearn import tree
# 假设训练集有X(预测器)和Y(目标),测试集有x_test(预测器)
# 构造树模型
model = tree.DecisionTreeClassifier(criterion='gini')
# model = tree.DecisionTreeRegressor() 回归
# 使用训练集训练模型
model.fit(X, y)
model.score(X, y)
# 输出预测值
predicted= model.predict(x_test)
“集成”的可以理解为群,集成方法包括一组预测模型,以达到更好的精度和模型稳定性。已知的集成方法最大限度的提高了树模型的效果。
像所有其他模型一样,基于树的模型也遭受着偏差和方差的困扰。偏差是指预测值的平均值与实际值之间的差异;方差是指,如果不同的样本来自同一个样本集,那么模型在同一点上的预测会有多大的不同。
我们建立一棵小树,然后得到一个低方差和高偏差的模型。该如何来平衡模型?
通常,当增加模型的复杂性时,由于模型中的偏差降低会导致预测误差降低。但当继续使模型变得更复杂时,最终模型会过拟合,模型的方差会越来越大。
一个好的模型应该保持这两种类型的错误之间的平衡,称为偏差和方差的权衡管理。集成学习则是实现这种平衡的一种方式。
一些常用的集成方法包括:Bagging,Boosting和Stacking。在本教程中,我们将详细讨论Bagging和Boosting。
Bagging是一种通过组合相同数据集中不同子集上多分类器的方法降低预测方差的技术,下图表示的比较清楚:
(1).创建多个数据集:
(2).建立多个分类器:
(3).组合分类器:
注意,在这里建立的模型的数量不是一个超参数。数量多的模型总是比数量少的模型更好,或者说可以更优的性能。理论上看,在某些假设下,组合预测的方差将减小到原始方差的$\frac{1}{N}$($n$:分类器的数量)。
Bagging模型有多种实现方式。随机森林是其中之一,我们将在下一步讨论。
随机森林被认为是数据科学的“灵丹妙药”,有趣的是,当你想不到其他算法时(不管情况如何),使用随机森林!
随机森林是一种通用的机器学习方法,能够处理回归和分类问题。他还负责数据降维,缺失值处理、离群值处理以及数据分析的其他基本步骤。他是一种集成学习方法,将一组效果一般的模型组合成一个强大的模型。
在随机森林中,与CART模型单个树不同,随机森林里我们生成有多棵决策树。为了根据属性对新对象进行分类,每个树都给出自己的分类意见,称为“投票”。在回归的情况下,森林选择选票最多的分类。
工作原理如下。每棵树的建立和生长如下:
随机森林的优点:
随机森林的缺点:
随机森林可以使用Python scikit-learn包实现,下面是Python加载随机森林模型的代码:
Python
# 导入库文件
from sklearn.ensemble import RandomForestClassifier
# 使用随机森林解决回归问题
# 假设训练集有X(预测器)和Y(目标),测试集有x_test(预测器)
# 构建随机森林模型
model= RandomForestClassifier(n_estimators=1000)
# 使用训练数据集训练模型
model.fit(X, y)
# 输出预测结果
predicted= model.predict(x_test)
定义:“Boosting”指的是将弱学习算法转化为强学习算法的一系列算法。
我们通过识别垃圾邮件问题来详细理解这个定义:
你怎么把电子邮件分类成垃圾邮件?和其他人一样,我们最初都是使用以下标准来识别“垃圾邮件”和“垃圾邮件”。如果:
上面,我们已经定义了多个规则来将电子邮件分类成“垃圾邮件”或“垃圾邮件”。但是,你认为这些规则是否足够强大,能够成功地对电子邮件进行分类?答案是否定的。
单独地这些规则不足以将电子邮件归类为“垃圾邮件”或“垃圾邮件”。因此,这些规则被称为弱学习法。
为了将弱学习方法转变为强学习方法,我们使用如下方法将每个弱学习方法联合起来进行预测:
例如,我们定义了5个弱学习器。在这5个弱学习器中,3个投“垃圾邮件”,2个投“不是垃圾邮件”。一般情况下,我们认为这个邮件是垃圾邮件,因为“垃圾邮件”的得票更高。
工作原理
现在我们知道,Boosting将多个弱学习器集合成一个强学习器。你应该会想到的一个问题是:“Boosting”如何识别弱学习?。
为了找到弱规则,我们在不同的分布上应用基础学习(ML)算法。应用基础学习算法生成一个新的弱预测规则。这是一个迭代过程, 经过多次迭代,Boosting将这些弱学习方法组合成单个强学习方法。
另一个困扰你的问题:“我们如何选择每一轮不同的分配?”。
为了选择正确的分布,有以下步骤:
最后,结合弱学习方法的输出,创建一个强学习方法,最终提高模型的预测能力。Boosting更关注被错误分类或者弱学习方法误差较高的样本。
有许多Boosting算法,可以用来提高模型精度。在本教程中,我们了解最常用的两种算法,即梯度(GBM)和XGBoost。
我一直很钦佩XGBoost算法的增强功能。有时,与GBM实现相比,XGBoost提供了更好的结果。但有时,会发现这只是微不足道的。当我探索更多关于他的性能和高准确性背后的科学,我发现在XGBoost相比GBM有很多优点:
(1).正则化:
(2).并行处理:
(3).灵活性高:
(4).处理缺失值:
(5).树的剪枝:
(6).交叉验证:
(7).可扩展现有模型:
在我们开始工作之前,让我们快速了解这个算法的重要参数和工作。这对R和Python用户都很有帮助,下面是GBM算法伪代码:
这是对GBM工作的一种极其简化的解释,有助于每个初学者理解这个算法。
使用重要的GBM参数在Python中改进模型性能:
(1).学习率
(2).n-估计量
(3).子样本
除此之外,还有一些影响整体功能的其他参数:
(1).损失
(2).初始化
(3).随机状态
(4).冗余
模型拟合时要打印的输出类型。不同值的意义:
(5).热启动
(6).预选
我知道他有一长串的参数,我已经在Excel文件中简化了,可以从这个GitHub repository下载。
我已经在Python中共享了标准代码。在末尾,需要在代码中添加自己使用的因变量和数据集名称。
# 导入库文件
from sklearn.ensemble import GradientBoostingClassifier # 分类
from sklearn.ensemble import GradientBoostingRegressor # 回归
# 使用GBM函数
clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0, max_depth=1)
clf.fit(X_train, y_train)
基于树的算法对于每个数据科学家来说都是很重要的。事实上,树模型在整个机器学习算法家族中性能最好。在本教程中,我们学习了GBM和XGBoost。现在已到了本教程的结尾。我们从零开始讨论基于树的建模,了解了决策树的重要性,以及如何使用简单的概念来改进算法。为了更好的理解,我们建议你进一步实践这些算法。此外,请注意与Boosting算法相关的参数,希望本教程能增加你对树模型的了解。
源自: ANALYTICS VIDHYA CONTENT TEAM——A Complete Tutorial on Tree Based Modeling from Scratch (Python)