不管是在Kaggle这类竞赛中,仍是商业环境,决策树回归器都已是最经常使用的机器学习算法之一。决策树可用于分类和回归问题。本文介绍了决策树回归器算法以及一些高级话题。html
介绍
ios
重要术语算法
它是如何工做的?数组
如何为决策树拆分决策?bash
问答网络
何时不用?dom
优势和缺点机器学习
避免过分拟合的技巧函数
决策树与随机森林性能
Sklearn决策树的超参数
基于树的模型VS线性模型
决策树模型的可视化
结论
参考
Photo by Todd Quackenbush / Unsplash-
决策树能够用如下要点归纳:
决策决策树是使用一组二进制规则来计算目标值的预测模型
每一个个体树都是一个简单的模型,有分支,节点和叶子
在深刻研究以前,让咱们看一下决策树的基本术语:
根节点:它表明整个整体或样本,并进一步拆分为两个或更多个同类集。
拆分:将节点划分为两个或更多个子节点的过程。
决策节点:当子节点分裂成更多的子节点时,它被称为决策节点。
叶子/终端节点:不拆分的节点称为叶子或终端节点。
剪枝:删除决策节点的子节点,此过程称为剪枝。能够认为是拆分的反过程。
分支/子树:整个树的子部分称为分支或子树。
父节点和子节点:划分出子节点的节点称为子节点的父节点,而子节点是父节点的子节点。
决策树经过向数据提出一系列问题来实现估计值,每一个问题都会缩小可能值的范围,直到模型足够自信地进行单个预测。问题的顺序及其内容由模型决定。此外,提出的问题都是真/假的形式。
这有点难以掌握,由于它不是人类天然思考的方式,也许显示这种差别的最好方法是建立一个真正的决策树。在上述问题中X1,X2是两个特征,它们容许咱们经过询问真/假来对目标变量y进行预测。
对于每一个真/假的答案,都有单独的分支。不管问题的答案如何,咱们最终都会实现一个预测(叶节点)。从顶部的根节点开始,而后在树中继续回答问题。因此给出任何一对X1,X2。
我应该提到的决策树的一个方面是它实际是如何学习的(如何造成'问题'以及如何设置阈值)。做为监督机器学习模型,决策树学习将数据映射到训练模型构建的输出上。
在训练期间,模型将拟合任何与问题域相关的历史数据,以及咱们但愿模型预测的真实值。该模型将学习数据和目标变量之间的关系。
在训练阶段以后,决策树产生相似于上图所示的树,计算最佳问题以及要求的顺序,以便可以进行最准确的估计。当咱们想要进行预测时,应该向模型提供相同的数据格式。预测将是基于训练过的训练数据集产生估计值。
制定拆分的策略会严重影响树的准确性。对分类和回归树来讲决策标准不一样。决策树回归器一般使用均方偏差(MSE)来决定将节点分红两个或更多个子节点。
假设咱们正在作二叉树,算法首先会选择一个值,而后将数据拆分为两个子集。对于每一个子集,它将分别计算MSE。树将会选择具备最小MSE值的结果的值。
让咱们来看一下Splitting如何决定决策树回归器的更多细节。建立树的第一步是建立第一个二元决策。你打算怎么作?
咱们须要选择一个变量和要拆分的值,以使两个组尽量彼此不一样。
对于每一个变量,对于该变量的可能值的每一个可能值,查看哪一个更好。
如何判断它是否更好?取两个新节点的加权平均值(mse * num_samples)。
那么咱们如今有:
一个表示拆分的效果的数字,是两组建立的平均平方偏差的加权平均值。
找到最佳拆分的方法,即尝试每一个变量和该变量的每一个可能值,并查看哪一个变量和哪一个值为咱们提供了最佳得分的划分。
这是建立决策树回归器的所有内容,而且当知足一些中止条件(由超参数定义)时将中止:
达到要求的限制时(例如max_depth)。
当你的叶子节点中只有一项(可能没有进一步划分,训练的MSE将为零,可是对其余数据集可能会过分拟合 - 不是一个有用的模型)。
是否有划分红3组的状况?
没有必要在一个级别上进行屡次划分,由于您能够再进一步拆分它们。
它是如何进行预测的?
给定一个数据点,您能够在整个树中运行它,询问真/假,直到它到达叶节点为止。最终预测是该叶节点中因变量的值的平均值。
由于咱们尝试了每一个变量和每一个变量可能的值来决策一个拆分。训练的计算成本会很高吗?
在这里,咱们要记住,当今计算机的CPU性能是以千兆赫兹来衡量的,即每秒数十亿个时钟周期,它有多个核心,每一个核心都有一个称为单指令、多数据(SIMD)的东西,它能够一次对每一个核心进行8次计算。此外,若是您使用的是GPU,那么这个过程会更快,由于它的性能是以teraflops来衡量的,因此每秒要进行数万亿次浮点运算。因此,这就是设计算法的地方,仅仅是人类很难意识到,考虑到当今计算机的速度有多快,算法应该多么愚蠢。总而言之,有至关多的操做,可是每秒数万亿次的速度几乎注意不到。
每一个节点的MSE计算哪一个底层模型?
基础模型只是数据点的平均值。对于初始根节点,咱们只是预测了全部训练数据点的因变量平均值。另外一个可能的选择是不用平均数来使用中位数,或者咱们甚至能够运行一个线性回归模型。咱们能够作不少事情,但在实践中,平均值很是有效。它们确实存在在随机森林模型中,其中叶节点是独立的线性回归,但应用并不普遍。
给定相同的数据和超参数,深度为n的DT将包含深度为n-1的DT?
所以,若是咱们建立一个深度为3的树和另外一个咱们摆脱最大深度的树,那么没有最大深度约束的树将包含深度为3的树。这假设数据和超参数将是相同的而且没有添加随机性(更深的树将包含不太深的树)。
如前所述,若是提供给划分预测的数据与训练数据无关,决策树将没法作出准确的预测。让咱们用一个例子来证实这个论点:
import numpy as npimport matplotlib.pyplot as pltfrom sklearn.tree import DecisionTreeRegressorx = np.linspace(0,1)y = x + np.random.uniform(-0.2,0.2,x.shape)plt.scatter(x,y)复制代码
咱们如今要构建一个决策树模型,这其实是一个时间序列问题。因此我打算将左侧部分做为训练集。并将右侧部分做为咱们的验证集。
# train, validation set splitx_trn, x_val = x[:40,None], x[40:,None]y_trn, y_val = y[:40,None], y[40:,None]# fit a modelm = DecisionTreeRegressor(max_depth=6).fit(x_trn, y_trn)复制代码
请注意,决策树回归器指望二维数组,而不是二维数组中的一维数组。
咱们如今绘制结果:
plt.scatter(x_val,m.predict(x_val),color='blue',label='Prediction') plt.scatter(x_val,y_val,color='red',label='Actual') plt.scatter(x_trn,m.predict(x_trn),color='blue') plt.scatter(x_trn,y_trn,color='red') plt.legend(loc='upper left')复制代码
若是您不知道决策树如何工做,那么这将使模型无用。换句话说,决策树和基于树的模型一般没法推断出他们之前从未见过的任何类型的数据,特别是将来的时间段,由于它只是平均它已经看到的数据。
简而言之,决策树和基于树的模型通常只作一个聪明的最邻近法。
在这种问题中,任何基于树的算法都没有用,首选模型是神经网络或线性回归模型。缘由是当你想要使用一个模型,而它有一个函数或者形状,它能够很好地进行外推。
决策树的一个主要缺点是它们容易过分拟合。这就是为何不多使用他们,而是使用其余基于树的模型,如随机森林和XGBoost。
总之,决策树和通用基于树的模型是一种监督学习算法(具备预约义的目标变量),主要用于分类问题。如上所述,当且仅当目标变量位于训练数据集中值的范围内时,它们才用于回归问题。
优点
它可用于分类和回归问题有时间作的好一点。
易于理解,解释,可视化。
在数据探索中颇有用:决策树是识别最重要变量和两个或多个变量之间关系的最快方法之一。借助决策树,咱们能够建立新的变量/特征,这些变量/特征具备更好的预测目标变量的能力。
须要更少的数据准备:它不受异常值和缺失值的影响。
数据类型不是约束:它能够处理数值和分类变量。
非参数方法:决策树被认为是非参数方法。这意味着决策树没有关于空间分布和分类器结构的假设。
能够捕获非线性关系。
劣势
过拟合:过拟合是决策树模型最实际的难点之一。经过设置模型参数约束和剪枝(下面详细讨论)能够解决这个问题。
不适合连续变量:在处理连续数值变量时,决策树在对不一样类别的变量进行分类时会丢失信息。
没法推断。
决策树可能不稳定:数据的微小变化可能致使生成彻底不一样的树。这称为方差,须要经过bagging 和 boosting等方法下降。
没法保证返回全局最优决策树。这能够经过训练多个树来弥补,其中特征和样本随替换而随机取样。
一般,您可能会发现您的模型与数据过分匹配,这一般会在引入新数据时损害模型的性能。若是决策树没有限制集,它会在训练集上给你一个零MSE,由于在更糟的状况下,它最终会为每次观察生成一个叶子。所以,在训练决策树时,防止过分拟合很是重要,能够经过如下方式进行:
设置树大小的约束(微调超参数)
树剪枝
使用随机森林
让咱们简单地讨论这些方面。
这能够经过微调树的一些超参数来完成。首先,让咱们看一下决策树的通常结构:
经过了解树建模中使用的参数的做用,能够帮助您在R&Python中更好地微调决策树。
节点拆分的最小样本
定义要考虑拆分的节点中所需的最小样本数(或观测值)。
用于控制过分拟合。较高的值会阻止模型学习与树选择的特定样本高度特别的关系。
过高的值会致使欠拟合,所以应该当心微调。
终端节点的最小样本(叶子)
定义终端节点或叶子中所需的最小样本(或观察值)。
用于控制过分拟合,相似于节点拆分的最小样本。
过高的值会致使欠拟合,所以应该当心微调。
树的最大深度(垂直深度)
用于控制过分拟合,由于更高的深度将使模型学习特定样本的关系。
过高的值会致使过分拟合,所以应当心微调。
拆分须要考虑的最大特征
搜索最佳拆分时要考虑的特征数量。这些将是随机选择的。
根据经验法则,特征总数的平方根很是有效,但咱们应该检查特征总数的30-40%。
较高的值可能致使过分拟合,但取决于具体状况。
如前所述,设置约束的技术是一种贪婪方法。换句话说,它将当即检查最佳划分并向前移动,直到达到指定的中止条件之一。
决策树算法中出现的问题之一是最终树的最佳大小。太大的树存在过分拟合训练数据的风险,而且很难推广到新样本。小树可能没法捕获有关样本空间的重要结构信息。可是,很难判断树算法什么时候应该中止,由于没法判断添加单个额外节点是否会显着减小错误。这个问题被称为地平线效应。一种常见的策略是扩展树,直到每一个节点包含少许实例,而后使用剪枝来删除不提供其余信息的节点。
剪枝应该减少学习树的大小,而不下降交叉验证集测量的预测精度。在用于优化性能的测量中,有许多不一样的剪枝技术。
最简单的剪枝形式之一是减小错误剪枝。从叶子开始,每一个节点都用其平均值替换。若是MSE不受影响,则保留更改。虽然有点天真,但减小错误剪枝具备简单和迅速的优势。
彷佛没有多少人真正花时间去剪枝决策树或进行微调,而是选择使用随机森林回归器(决策树集合),它比单个优化树更不容易过分拟合,性能更好。
在随机森林上使用决策树的常见论点是,决策树更容易解释,您只需查看决策树逻辑便可。然而,在一个随机森林中,您不须要研究500个不一样树的决策树逻辑。
同时,随机森林其实是决策树的集合,这使得算法对于实时预测来讲缓慢且无效。通常来讲,RF能够快速训练,可是一旦训练开始就会很慢地建立预测。这是由于它必须对每棵树进行预测,而后进行平均以建立最终预测。(解决方法能够是同时使用不一样树的集群)
更准确的预测须要更多的树,这会致使模型变慢。在大多数实际应用中,随机森林算法速度足够快,但在某些状况下,运行时性能是很重要的,因此会首选其余方法。
最后,决策树确实存在过分拟合问题,而随机森林能够防止过分拟合,从而在大多数状况下获得更好的预测。这是随机森林回归模型事实的一个显著优点,使其对许多数据科学家更具吸引力。
min_samples_leaf :int,float,optional(default = 1)
它是咱们上面讨论的终端节点的最小样本数。
若是是int,则将min_samples_leaf视为最小数字。
若是是float,则min_samples_leaf是一个百分比,ceil(min_samples_leaf * n_samples)是每一个节点的最小样本数。
min_samples_split:int,float,optional(default = 2)
它是咱们上面讨论的节点拆分的最小样本。
若是是int,则将min_samples_split视为最小数字。
若是是float,则min_samples_split是一个百分比,ceil(min_samples_split * n_samples)是每一个拆分的最小样本数。
max_features:int,float,string或None,optional(default =“auto”)
寻找最佳拆分时要考虑的特征数量:
若是是int,则在每次拆分时考虑max_features特征。 - 若是是浮点数,则max_features是百分比,而且在每次拆分时都会考虑int(max_features * n_features)要素。
若是是“auto”,则max_features = sqrt(n_features)。
若是是“sqrt”,则max_features = sqrt(n_features)(与“auto”相同)。
若是是“log2”,则max_features = log2(n_features)。
若是为None,则max_features = n_features。
max_depth :整数或无,可选(默认=无)
树的最大深度。若是为None,则扩展节点直到全部叶子都是纯的或直到全部叶子包含少于min_samples_split样本。
实际上,您可使用任何算法。这取决于您要解决的问题类型。让咱们看一些关键因素,它们将帮助您决定使用哪一种算法:
若是依赖变量和自变量之间的关系用线性模型很好地逼近,线性回归将优于基于树的模型。
若是因变量和自变量之间存在高度的非线性和复杂关系,树模型将优于经典的回归方法。
若是你须要创建一个易于向人们解释的模型,决策树模型老是比线性模型作得更好。决策树模型比线性回归更容易解释!
让咱们用一个例子证实咱们在第1点和第2点的论证:
import numpy as npimport matplotlib.pyplot as pltfrom sklearn.tree import DecisionTreeRegressorfrom sklearn.linear_model import LinearRegressionplt.figure(figsize=(20,10))x = np.linspace(0,2,10000)y = 1+ 3*xplt.scatter(x,y)复制代码
咱们如今要构建决策树和线性模型。咱们指望线性模型完美拟合,由于目标变量与特征x线性相关。所以,我将对数据进行无序处理,将70%视为训练集,将30%视为验证。
idxs_train = sorted(np.random.permutation(len(x))[:int(0.7*len(x))])idx_test = [i for i in range(0,len(x)) if i not in idxs_train]# train, validation set splitx_trn, x_val = x[idxs_train,None], x[idx_test,None]y_trn, y_val = y[idxs_train,None], y[idx_test,None]# fit a modeldt = DecisionTreeRegressor(max_depth=3).fit(x_trn, y_trn)l = LinearRegression().fit(x_trn, y_trn)复制代码
请注意,两个模型都指望二维数组。咱们如今绘制结果:
plt.figure(figsize=(20,10))plt.scatter(x,dt.predict(x[:,None]),color='blue',label='Prediction DT')plt.scatter(x,l.predict(x[:,None]),color='green',label='Prediction Linear')plt.scatter(x,y,color='red',label='Actual')plt.legend(loc='upper left')复制代码
在某种程度上,决策树试图适应 staircase。显然,在这种状况下,线性模型运行得很好,但在目标变量与输入特征不线性相关的其余状况下,DT将是更好的选择,由于它可以捕获非线性。另请参阅如下SciKit学习文档中的另外一个示例:
可视化决策树很是简单。让咱们绘制上面训练过的决策树。
首先,咱们须要导入一些额外的库:
from sklearn.tree import export_graphvizimport IPython, graphviz, re, math复制代码
而后咱们能够简单地绘制决策树,以下所示:
def draw_tree(t, col_names, size=9, ratio=0.5, precision=3): """ Draws a representation of a random forest in IPython. Parameters: ----------- t: The tree you wish to draw df: The data used to train the tree. This is used to get the names of the features. """ s=export_graphviz(t, out_file=None, feature_names=col_names, filled=True, special_characters=True, rotate=True, precision=precision) IPython.display.display(graphviz.Source(re.sub('Tree {', f'Tree {{ size={size}; ratio={ratio}',s)))col_names =['X']draw_tree(dt, col_names, precision=3)复制代码
如您所见,咱们正在获取数据的子集,并决定进一步划分子集的最佳方式。咱们的初始子集是整个数据集,咱们根据规则对其进行拆分X<=1.001。而后,对于每一个子集,咱们执行额外的拆分,直到咱们可以正确地预测目标变量,同时遵照约束max_depth=3。
决策树是最普遍使用的机器学习模型之一,由于它们能够很好地处理噪声或丢失的数据,而且能够很容易地进行整合以造成更强大的预测器。此外,您能够直接看到模型的学习逻辑,这意味着它是一个很是受欢迎的模型,适用于模型可解释性很重要的领域。
感谢阅读,我期待着听到你的问题,敬请关注并快乐机器学习。
https://scikit-learn.org/stable/modules/tree.html
https://en.wikipedia.org/wiki/Decision_tree_pruning
https://stackoverflow.com/questions/49428469/pruning-decision-trees