页面树结构

2017-11-09 ApacheCN 开源组织,第二期邀请成员活动,一起走的更远 : http://www.apachecn.org/member/209.html


MachineLearning 优酷地址 : http://i.youku.com/apachecn

转至元数据结尾
转至元数据起始

集成方法的目标是结合使用给定学习算法构建的几个基本估计器的预测,以便通过单个估计器来提高泛化/鲁棒性。

通常区分两个系统的集合方法:

  • 平均方法中,驱动原则是独立构建几个估计量,然后平均其预测。平均来说,组合估计器通常比单个基准估计器更好,因为它的方差减小。

    示例: Bagging方法 随机树木森林 ...

  • 相比之下,在提升方法中,依次构建基本估计量,并尝试减少组合估计量的偏差。动机是组合几个弱模型来产生一个强大的合奏。

    示例:AdaBoost渐变树提升,...

 

Bagging元估计

在集成的算法,bagging方法形成的一类,其建立在原有训练集的随机子集黑匣子估计的几个实例,然后汇总它们各自的预测,以形成最终的预测算法。这些方法被用作减少基本估计量(例如决策树)的方差的方式,通过将随机化引入到其构建过程中,然后将其合并出来。在许多情况下,装袋方法构成了一种非常简单的改进单一模型的方式,而不需要适应基础的基本算法。由于它们提供了一种减少过度装配的方式,所以采用强大而复杂的模型(例如,完全开发的决策树),装袋方法最有效,与通常用弱模型最好的增强方法(例如,

装袋方法有许多风格,但是通过绘制训练集的随机子集的方式彼此大不相同:

  • 当数据集的随机子集被绘制为样本的随机子集时,则该算法被称为粘贴[B1999]
  • 当抽取样品时,该方法称为Bagging [B1996]
  • 当数据集的随机子集被绘制为特征的随机子集时,则该方法被称为随机子空间[H1998]
  • 最后,当基本估计器建立在样本和特征的子集上时,该方法被称为随机补丁[LG2012]

在scikit学习,套袋方法是提供一个统一的 BaggingClassifier元估计(相应的BaggingRegressor),作为输入与指定绘制随机子集的策略参数沿用户指定的基本估计。特别地,max_samples 并且max_features控制子集的大小(在样本和特征方面),同时bootstrapbootstrap_features控制是否抽出样本和特征。当使用可用样本的子集时,可以通过设置通过样品外样品估算泛化精度oob_score=True。例如,下面的代码片段展示了如何实例化一个KNeighborsClassifier基准估计器的装袋集合 ,每一个基于估计的50%的随机子集和50%的特征。

>>> from sklearn.ensemble import BaggingClassifier
>>> from sklearn.neighbors import KNeighborsClassifier
>>> bagging = BaggingClassifier(KNeighborsClassifier(),
...                             max_samples=0.5, max_features=0.5) 

例子:

参考

[B1999]L. Breiman, “Pasting small votes for classification in large databases and on-line”, Machine Learning, 36(1), 85-103, 1999.
[B1996]L. Breiman, “Bagging predictors”, Machine Learning, 24(2), 123-140, 1996.
[H1998]T. Ho, “The random subspace method for constructing decision forests”, Pattern Analysis and Machine Intelligence, 20(8), 832-844, 1998.
[LG2012]G. Louppe and P. Geurts, “Ensembles on Random Patches”, Machine Learning and Knowledge Discovery in Databases, 346-361, 2012.

随机树的森林

sklearn.ensemble模块包括基于随机决策树的两个平均算法:RandomForest算法和Extra-Trees方法。这两种算法都是针对树木设计的扰动和组合技术[B1998]。这意味着通过在分类器构造中引入随机性来创建一组不同的分类器。集合的预测作为单个分类器的平均预测给出。

作为其他分类器,森林分类器必须配备两个数组:保存训练样本的大小的稀疏或密集数组X以及保存训练样本的目标值(类标签)的大小的数组Y :[n_samples, n_features][n_samples]

>>> from sklearn.ensemble import RandomForestClassifier
>>> X = [[0, 0], [1, 1]]
>>> Y = [0, 1]
>>> clf = RandomForestClassifier(n_estimators=10)
>>> clf = clf.fit(X, Y) 

决策树一样,树林也扩展到多输出问题 (如果Y是一个大小的数组 )。[n_samples, n_outputs]

随机森林 

在随机森林(参见RandomForestClassifier和 RandomForestRegressor类)中,集合中的每个树都是从训练集中替换(即,引导样本)抽取的样本构建的。另外,当在树的构建期间分割节点时,所选择的分割不再是所有特征中最好的分割。相反,所选的分割是特征的随机子集中的最佳分割。由于这种随机性,森林的偏差通常略微增加(相对于单个非随机树的偏差),但是由于平均,其方差也减小,通常大于补偿偏差的增加,从而产生更好的模型。

与原始出版物[B2001]相反,scikit学习实现通过对分类器进行平均,将其概率预测相结合,而不是让每个分类器对单个类进行投票。

极端随机树 

在非常随机的树(参见ExtraTreesClassifier 和ExtraTreesRegressor类)中,随机性进一步分离计算的方式。如在随机森林中,使用候选特征的随机子集,而不是寻找最具有歧视性的阈值,而是为每个候选特征随机绘制阈值,并且将这些随机生成的阈值中的最佳值作为分割规则。这通常允许更多地减少模型的方差,牺牲稍微更大的偏差增加:

>>> from sklearn.model_selection import cross_val_score
>>> from sklearn.datasets import make_blobs
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.ensemble import ExtraTreesClassifier
>>> from sklearn.tree import DecisionTreeClassifier

>>> X, y = make_blobs(n_samples=10000, n_features=10, centers=100,
...     random_state=0)

>>> clf = DecisionTreeClassifier(max_depth=None, min_samples_split=2,
...     random_state=0)
>>> scores = cross_val_score(clf, X, y)
>>> scores.mean()                             
0.97...

>>> clf = RandomForestClassifier(n_estimators=10, max_depth=None,
...     min_samples_split=2, random_state=0)
>>> scores = cross_val_score(clf, X, y)
>>> scores.mean()                             
0.999...

>>> clf = ExtraTreesClassifier(n_estimators=10, max_depth=None,
...     min_samples_split=2, random_state=0)
>>> scores = cross_val_score(clf, X, y)
>>> scores.mean() > 0.999
True 

参数

使用这些方法时要调整的主要参数是n_estimators 和max_features。前者是森林里的树木数量。越大越好,而且计算时间越长。此外,请注意,超过关键数量的树木,结果将停止显着改善。后者是分割节点时要考虑的特征的随机子集的大小。偏差减小越大,偏差越大。经验良好的默认值max_features=n_features 用于回归问题,max_features=sqrt(n_features)分类任务(n_features数据中的功能数量在哪里)。通常max_depth=None 结合min_samples_split=1(即,完全开发树木)时,会获得良好的效果。请记住,这些值通常不是最佳的,并且可能导致使用大量RAM的模型。应始终交叉验证最佳参数值。bootstrap=True另外,请注意,在随机林中,默认使用引导样本( ),而外部树的默认策略是使用整个数据集(bootstrap=False)。当使用引导抽样时,可以在左边或外面的样本上估算泛化精度。这可以通过设置启用oob_score=True。当使用引导抽样时,可以在左边或外面的样本上估算泛化精度。这可以通过设置启用。当使用引导抽样时,可以在左边或外面的样本上估算泛化精度。这可以通过设置启用。

并行化

最后,该模块还具有树的并行构建和通过n_jobs 参数的预测的并行计算。如果n_jobs=k然后计算被划分为 k作业,并k在机器的内核上运行。如果n_jobs=-1 然后使用机器上可用的所有核心。请注意,由于进程间通信开销,加速可能不是线性的(即,k不幸的是使用作业不会k那么快)。当建立大量的树,或者构建单个树需要相当长的时间(例如大型数据集)时,仍然可以实现显着的加速。

参考

[B2001]
  1. Breiman, “Random Forests”, Machine Learning, 45(1), 5-32, 2001.
[B1998]
  1. Breiman, “Arcing Classifiers”, Annals of Statistics 1998.
[GEW2006]P. Geurts, D. Ernst., and L. Wehenkel, “Extremely randomized trees”, Machine Learning, 63(1), 3-42, 2006.

特征重要性评估 

用作树中决策节点的特征的相对等级(即深度)可用于评估该特征相对于目标变量的可预测性的相对重要性。在树顶部使用的特征有助于输入样本的较大部分的最终预测决策。因此他们贡献的样本预期分数可以用作对特征相对重要性的估计。

通过在几个随机树中平均这些预期活动率,可以减少这种估计的方差,并将其用于特征选择。

以下示例显示了使用ExtraTreesClassifier模型的面部识别任务的每个像素的相对重复性的颜色编码表示。

实际上,这些估计值作为feature_importances_在拟合模型上命名的属性存储 。这是一个数组,(n_features,)其形状为正值,总和为1.0。值越高,匹配特征对预测函数的贡献越重要。

例子:

全部随机树嵌入 

RandomTreesEmbedding实现数据的无监督转换。使用完全随机树的森林,RandomTreesEmbedding 通过数据点最后的叶子的索引来对数据进行编码。然后,该索引以K方式编码,导致高维稀疏二进制编码。可以非常有效地计算该编码,然后可以将其用作其他学习任务的基础。可以通过选择树的数量和每棵树的最大深度来影响代码的大小和稀疏性。对于集合中的每个树,编码包含一个条目。编码的大小最多是森林中最大叶数。n_estimators * 2 ** max_depth

随着相邻数据点更可能位于树的同一叶内,变换执行隐式非参数密度估计。

例子:

也可以看看:歧管学习技术也可用于导出特征空间的非线性表示,而且这些方法也集中于降维。

AdaBoost

该模块sklearn.ensemble包括1995年由Freund和Schapire [FS1995]推出的流行的升压算法AdaBoost 。

AdaBoost的核心原则是在数据的反复修改版本上适应一系列弱学习者(即,仅比稍微优于随机猜测的模型,如小决策树)。然后将所有这些预测通过加权多数票(或总和)合并以产生最终预测。在每一个所谓的提高迭代的数据修改由施加权重的W_1W_2......,w_N 每个训练样本。最初,这些权重都被设置为 ,所以第一步只是训练一个弱学习者的原始数据。对于每个连续迭代,样本权重被单独修改,并且将学习算法重新应用于重新加权的数据。在给定的步骤, 那些在前一步骤诱发的增强模型不正确预测的训练样本的权重增加,而正确预测的那些训练样本的权重则会降低。随着迭代的进行,难以预测的示例将会受到越来越大的影响。因此,每个后续的弱小的学习者被迫集中在序列[HTF]中被先前错过的例子。

AdaBoost可用于分类和回归问题:

用法 

以下示例显示了如何使用100个弱学习者适合AdaBoost分类器:

>>> from sklearn.model_selection import cross_val_score
>>> from sklearn.datasets import load_iris
>>> from sklearn.ensemble import AdaBoostClassifier

>>> iris = load_iris()
>>> clf = AdaBoostClassifier(n_estimators=100)
>>> scores = cross_val_score(clf, iris.data, iris.target)
>>> scores.mean()                             
0.9... 

弱学习者的数量由参数控制n_estimators。该 learning_rate参数控制弱学习者在最终组合中的贡献。默认情况下,弱学习者是决策树桩。可以通过base_estimator参数指定不同的弱学习者。调整以获得良好结果的主要参数n_estimators是基本估计器的复杂性(例如,在决策树的情况下,其深度max_depth或最小所需样本数min_samples_leaf)。

例子:

参考

[FS1995]Y. Freund和R. Schapire,“A Decision-Theoretic Generalization on On-Line Learning and a Application to Boosting”,1997。
[ZZRH2009]J. Zhu,H. Zou,S. Rosset,T. Hastie。“多类AdaBoost”,2009。
[D1997]
  1. 德鲁克。“Improving Regressors using Boosting Techniques”,1997。
[HTF]T. Hastie,R. Tibshirani和J. Friedman,“Elements of Statistical Learning Ed。2“,Springer,2009。

渐变树提升

渐变树提升 或渐变增强回归树(GBRT)是推广到任意可微分损失函数的推广。GBRT是一个准确有效的现成程序,可用于回归和分类问题。梯形树提升模型用于各种领域,包括网络搜索排名和生态学。

GBRT的优点是:

  • 混合型数据的自然处理(=异构特征)
  • 预测力
  • 输出空间异常值的鲁棒性(通过强大的损失函数)

GBRT的缺点是:

  • 由于升压的顺序性,可扩展性几乎不能并行化。

该模块sklearn.ensemble提供了通过梯度增强回归树进行分类和归一化的方法。

分类

GradientBoostingClassifier支持二进制和多类分类。以下示例显示如何将具有100个决策树枝的渐变增强分类器作为弱学习者:

>>> from sklearn.datasets import make_hastie_10_2
>>> from sklearn.ensemble import GradientBoostingClassifier

>>> X, y = make_hastie_10_2(random_state=0)
>>> X_train, X_test = X[:2000], X[2000:]
>>> y_train, y_test = y[:2000], y[2000:]

>>> clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0,
...     max_depth=1, random_state=0).fit(X_train, y_train)
>>> clf.score(X_test, y_test)                 
0.913... 

弱学习者(即回归树)的数量由参数控制n_estimators; 可以通过或通过设置叶节点数来设置树深度来控制每个树的大小。这是超范围(0.0,1.0)的超参数,通过收缩来控制过度拟合。max_depth max_leaf_nodes learning_rate

注意:超过2类的分类需要n_classes在每次迭代中诱导回归树,因此,诱导树的总数相等 。对于具有大量的类数据集,我们强烈推荐使用 作为替代。n_classes * n_estimatorsRandomForestClassifierGradientBoostingClassifier

回归

GradientBoostingRegressor支持一些 可以通过参数指定的 不同的回归 损失函数loss ; 回归的默认损失函数为最小二乘('ls')。 

>>> import numpy as np
>>> from sklearn.metrics import mean_squared_error
>>> from sklearn.datasets import make_friedman1
>>> from sklearn.ensemble import GradientBoostingRegressor

>>> X, y = make_friedman1(n_samples=1200, random_state=0, noise=1.0)
>>> X_train, X_test = X[:200], X[200:]
>>> y_train, y_test = y[:200], y[200:]
>>> est = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1,
...     max_depth=1, random_state=0, loss='ls').fit(X_train, y_train)
>>> mean_squared_error(y_test, est.predict(X_test))    
5.00... 

下图显示了GradientBoostingRegressor 向波士顿房价数据集(sklearn.datasets.load_boston)应用最小二乘法损失的结果和500位基础学习者的结果。左侧的情节显示了每次迭代的列车和测试错误。每次迭代的列车误差都存储在train_score_梯度提升模型的 属性中。每个迭代的测试误差可以通过staged_predict返回在每个阶段产生预测的发生器的方法获得。像这样的地块可以用来确定树木的最佳数量(即n_estimators早期停止)。右侧的情节显示可通过该feature_importances_属性获取的功能重要性。

例子:

配件额外的弱学习

两者GradientBoostingRegressorGradientBoostingClassifier 支持warm_start=True,允许您添加更多的估计器到已经适合的模型。

>>> _ = est.set_params(n_estimators=200, warm_start=True)  # set warm_start and new nr of trees
>>> _ = est.fit(X_train, y_train) # fit additional 100 trees to est
>>> mean_squared_error(y_test, est.predict(X_test))    
3.84... 

控制树的大小

回归树基础学习者的大小定义了梯度增强模型可以捕获的变量交互的级别。一般来说,深度树h可以捕获秩序的相互作用h。有两种方式可以控制单个回归树的大小。

如果你指定,max_depth=h那么完成深度的二进制树h就会生长。这样的树将具有(最多)2**h叶节点和分割节点。2**h - 1

或者,您可以通过参数指定叶节点的数量来控制树的大小max_leaf_nodes。在这种情况下,树木将以最先进的搜索方式生长,其中杂质提高最多的节点将首先扩大。max_leaf_nodes=k具有分割节点的树,因此可以模拟高达订单的交互。k - 1max_leaf_nodes - 1

我们发现,max_leaf_nodes=k提供可比较的结果,max_depth=k-1 但是以牺牲稍高的训练误差为代价来训练更快。参数max_leaf_nodes对应J[F2001]梯度提升章节中的变量,与interaction.depthR的gbm软件包中的参数相关。max_leaf_nodes == interaction.depth + 1

数学公式

GBRT考虑以下形式的加法模型:

在提升背景下通常被称为弱学习者的基础功能 在哪里。梯度树提升使用固定大小的决策树作为弱学习者。决策树具有许多能力,使其对于提升有价值,即处理混合类型的数据的能力和对复杂功能建模的能力。

与其他增强算法类似,GBRT以前向阶段方式构建添加模型:

在每个阶段,选择决策树以最小化大号给定当前模型 及其拟合的损失函数

初始模型是问题特定的,最小二乘回归通常选择目标值的平均值。

注意:也可以通过init 参数指定初始模型。传递的对象必须实现fitpredict

Gradient Boosting尝试通过最陡下降数字地解决这个最小化问题:最陡的下降方向是当前模型评估的损耗函数的负梯度,可以为任何可微分的损失函数计算:

使用行搜索选择步长的位置:

用于回归和分类的算法仅在使用的具体损失函数上有所不同。

损失函数

支持以下损失函数,可以使用以下参数指定loss
  • 回归
    • 最小二乘('ls'):由于其优越的计算性质,回归的自然选择。初始模型由目标值的平均值给出。
    • 最小绝对偏差('lad'):用于回归的强大的损失函数。初始模型由目标值的中值给出。
    • Huber('huber'):另一个结合最小二乘和最小绝对偏差的强大的损失函数; 用于alpha控制异常值的灵敏度(详见[F2001])。
    • 分位数('quantile'):分位数回归的损失函数。使用指定的位数。该损失函数可用于创建预测间隔(参见梯度增强回归的预测间隔)。0 < alpha < 1 
  • 分类
    • 二项式偏差('deviance'):二进制分类的负二项对数似然损失函数(提供概率估计)。初始模型由对数优势比给出。
    • 多项式偏差('deviance'):用于具有n_classes互斥类的多类分类的负多项式对数似然损失函数 。它提供概率估计。初始模型由每个类的先验概率给出。在每个迭代n_classes 回归中,必须构造树,这样使得GBRT对于具有大量类的数据集而言效率低下。
    • 指数损失('exponential'):与损失函数相同AdaBoostClassifier。较不坚固到错误标记的例子比'deviance'; 只能用于二进制分类。

正则化

收缩

[F2001]提出了一个简单的正规化策略,将每个弱势学习者的贡献扩大一个因素

该参数也称为学习率,因为它可以缩放梯度下降过程的步长; 它可以通过learning_rate参数设置。

参数learning_rate与参数强烈相互作用, n_estimators适合弱学习者的数量。较小的值learning_rate需要较大数量的弱学习者来维持不断的训练误差。经验证据表明,learning_rate偏好的偏好值更好的测试错误。[HTF2009] 建议将学习率设置为小常数(例如),并提前停止选择。为之间的相互作用的一个更详细的讨论 和见[R2007] learning_rate <= 0.1n_estimatorslearning_raten_estimators

子采样 

[F1999]提出了随机梯度增强,其结合梯度增强与引导平均(装袋)。在每个迭代中,基本分类器是对subsample可用训练数据的一小部分进行训练的。子样本被绘制而不需要更换。典型值为subsample0.5。

下图显示了收缩和二次采样对模型拟合优势的影响。我们可以清楚地看到,收缩优于无收缩。收缩采样可进一步提高模型的准确性。另一方面,没有收缩的二次采样效果差。

注意:使用一个小的max_features值可以显着减少运行时间。

随机梯度提升允许通过计算未包含在引导示例中的示例(即,外包示例)的偏差的改进来计算测试偏差的外包估计。这些改进存储在属性中 oob_improvement_oob_improvement_[i]如果将第i个阶段添加到当前预测中,则对OOB样本的损失进行改进。外包估算可用于模型选择,例如确定最佳迭代次数。OOB估计通常非常悲观,因此我们建议使用交叉验证,而只有在交叉验证太费时的情况下才使用OOB。

例子:

解释

通过简单地可视化树结构,可以轻松地解释个别决策树。然而,梯度增强模型包含数百个回归树,因此它们不能通过目视检查各个树容易地解释。幸运的是,已经提出了一些技术来总结和解释梯度增强模型。

功能重要性

特征通常不会有助于预测目标反应; 在许多情况下,大部分功能实际上是无关紧要的。在解释模型时,第一个问题通常是:这些重要特征是什么,它们如何有助于预测目标响应?

个别决策树通过选择适当的分割点来内在地执行特征选择。该信息可用于测量每个特征的重要性; 基本思想是:在树的分割点中使用的特征越多,该特征就越重要。通过简单地平均每个树的特征重要性,可以将这个重要性的概念扩展到决策树组合(有关更多细节,请参阅 功能重要性评估)。

适合梯度增强模型的特征重要度得分可以通过以下feature_importances_属性访问:

>>> from sklearn.datasets import make_hastie_10_2
>>> from sklearn.ensemble import GradientBoostingClassifier

>>> X, y = make_hastie_10_2(random_state=0)
>>> clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0,
...     max_depth=1, random_state=0).fit(X, y)
>>> clf.feature_importances_  
array([ 0.11,  0.1 ,  0.11,  ... 

例子:

部分依赖

部分依赖图(PDP)显示了目标响应与一组“目标”特征之间的依赖关系,使所有其他特征值(“补码”特征)边缘化。直观地,我们可以将部分依赖性解释为预期目标响应[1]作为“目标”特征的函数[2]

由于人类感知的限制,目标特征集的大小必须很小(通常为一个或两个),因此目标特征通常从最重要的特征中选出。

下图显示了加州房屋数据集的四个单向和一个双向部分依赖图:

单向PDP告诉我们目标响应与目标特征(例如线性,非线性)之间的相互作用。上图左上方显示了区内中位数收入对房价中位数的影响; 我们可以清楚地看到它们之间的线性关系。

具有两个目标特征的PDP显示了两个特征之间的相互作用。例如,上图中的双变量PDP显示房价中位数与家庭年龄和平均值联合值的依赖关系。每户住户 我们可以清楚地看到这两个特征之间的相互作用:平均 入住率大于2,房价几乎独立于房屋年龄,而对于小于2的房价,对年龄的依赖性很大。

该模块partial_dependence提供了一个方便的功能 plot_partial_dependence 来创建单向和双向部分依赖图。在下面的例子中,我们展示了如何创建一个部分依赖关系图的网格:两个单向PDP的功能01两个功能之间的双向PDP:

>>> from sklearn.datasets import make_hastie_10_2
>>> from sklearn.ensemble import GradientBoostingClassifier
>>> from sklearn.ensemble.partial_dependence import plot_partial_dependence

>>> X, y = make_hastie_10_2(random_state=0)
>>> clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0,
...     max_depth=1, random_state=0).fit(X, y)
>>> features = [0, 1, (0, 1)]
>>> fig, axs = plot_partial_dependence(clf, X, features)  
对于多类模型,您需要设置通过label参数创建PDP的类标签:
>>> from sklearn.datasets import load_iris
>>> iris = load_iris()
>>> mc_clf = GradientBoostingClassifier(n_estimators=10,
...     max_depth=1).fit(iris.data, iris.target)
>>> features = [3, 2, (3, 2)]
>>> fig, axs = plot_partial_dependence(mc_clf, X, features, label=0)  
如果您需要部分依赖函数的原始值而不是绘图,则可以使用该 partial_dependence函数:
>>> from sklearn.ensemble.partial_dependence import partial_dependence

>>> pdp, axes = partial_dependence(clf, [0], X=X)
>>> pdp  
array([[ 2.46643157,  2.46643157, ...
>>> axes  
[array([-1.62497054, -1.59201391, ... 

该函数需要一个参数grid,该参数指定应评估部分依赖函数的目标要素的值,或者Xgrid根据训练数据自动创建的方便模式的参数。如果X 给出,axes函数返回的值给出了每个目标特征的轴。

对于grid部分依赖函数中的“目标”特征的每个值需要边缘化树对所有可能的“补码”特征值的预测。在决策树中,可以有效地评估该功能,而不参考训练数据。对于每个网格点,执行加权树遍历:如果分割节点涉及“目标”特征,则跟随相应的左分支或右分支,否则跟随两个分支,每个分支由进入该分支节点的训练样本的分数加权科。最后,部分依赖由所有访问树叶的加权平均值给出。对于树组合,每个树的结果再次平均。

脚注

[1]对于loss='deviance' 目标响应的分类是logit(p)。
[2]更准确地说,它是对初始模型计算后的目标响应的期望值; 部分依赖图不包括init模型。

 

例子:

参考

[F2001](123) J. Friedman, “Greedy Function Approximation: A Gradient Boosting Machine”, The Annals of Statistics, Vol. 29, No. 5, 2001.
[F1999]
  1. Friedman, “Stochastic Gradient Boosting”, 1999
[HTF2009]
  1. Hastie, R. Tibshirani and J. Friedman, “Elements of Statistical Learning Ed. 2”, Springer, 2009.
[R2007]
  1. Ridgeway, “Generalized Boosted Models: A guide to the gbm package”, 2007

投票分类器

投票分类器实施背后的想法是将概念上不同的机器学习分类器结合起来,并使用多数投票或平均预测概率(软投票)来预测类标签。这样的分类器可以用于一组性能良好的模型,以平衡其个人的弱点。

大多数类标签(大多数/硬投票)

在多数投票中,特定样本的预测类标签是表示每个分类器预测的类标签的大多数(模式)的类标签。

例如,如果给定样本的预测是

  • 分类器1 - >类1
  • 分类器2 - >类1
  • 分类器3 - >类2

VotingClassifier(with voting='hard')将根据大多数类标签将样本分类为“类1”。

在系统的情况下,VotingClassifier将根据升序排序顺序选择该类。例如,在以下情况下

  • 分类器1 - >类2
  • 分类器2 - >类1

类标签1将被分配给样品。

用法

以下示例显示如何适合大多数规则分类器:

>>> from sklearn import datasets
>>> from sklearn.model_selection import cross_val_score
>>> from sklearn.linear_model import LogisticRegression
>>> from sklearn.naive_bayes import GaussianNB
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.ensemble import VotingClassifier

>>> iris = datasets.load_iris()
>>> X, y = iris.data[:, 1:3], iris.target

>>> clf1 = LogisticRegression(random_state=1)
>>> clf2 = RandomForestClassifier(random_state=1)
>>> clf3 = GaussianNB()

>>> eclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)], voting='hard')

>>> for clf, label in zip([clf1, clf2, clf3, eclf], ['Logistic Regression', 'Random Forest', 'naive Bayes', 'Ensemble']):
...     scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
...     print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))
Accuracy: 0.90 (+/- 0.05) [Logistic Regression]
Accuracy: 0.93 (+/- 0.05) [Random Forest]
Accuracy: 0.91 (+/- 0.04) [naive Bayes]
Accuracy: 0.95 (+/- 0.05) [Ensemble] 

加权平均概率(软投票)

与多数表决(硬投票)相反,软投票将类标签作为预测概率之和的argmax返回。

可以通过weights 参数将特定权重分配给每个分类器。当提供权重时,收集每个分类器的预测类概率,乘以分类器权重并进行平均。最终的类标签然后从具有最高平均概率的类标签导出。

为了用一个简单的例子来说明这一点,我们假设我们有三个分类器和一个3类分类问题,我们为所有分类器赋予相等的权重:w1 = 1,w2 = 1,w3 = 1。

然后,样本的加权平均概率计算如下:

分类1级2级3级
分类器1w1 * 0.2w1 * 0.5w1 * 0.3
分类器2w2 * 0.6w2 * 0.3w2 * 0.1
分类器3w3 * 0.3w3 * 0.4w3 * 0.3
加权平均0.370.40.23

这里,预测的类别标签是2,因为它具有最高的平均概率。

以下示例说明了当使用基于线性支持向量机,决策树和K最近邻分类器的软投票分类器时,决策区域可能如何改变:

>>> from sklearn import datasets
>>> from sklearn.tree import DecisionTreeClassifier
>>> from sklearn.neighbors import KNeighborsClassifier
>>> from sklearn.svm import SVC
>>> from itertools import product
>>> from sklearn.ensemble import VotingClassifier

>>> # Loading some example data
>>> iris = datasets.load_iris()
>>> X = iris.data[:, [0,2]]
>>> y = iris.target

>>> # Training classifiers
>>> clf1 = DecisionTreeClassifier(max_depth=4)
>>> clf2 = KNeighborsClassifier(n_neighbors=7)
>>> clf3 = SVC(kernel='rbf', probability=True)
>>> eclf = VotingClassifier(estimators=[('dt', clf1), ('knn', clf2), ('svc', clf3)], voting='soft', weights=[2,1,2])

>>> clf1 = clf1.fit(X,y)
>>> clf2 = clf2.fit(X,y)
>>> clf3 = clf3.fit(X,y)
>>> eclf = eclf.fit(X,y) 

 

使用VotingClassifierGridSearch 

所述VotingClassifier也可以加合使用GridSearch为了调整个体估计量的超参数:

>>> from sklearn.model_selection import GridSearchCV
>>> clf1 = LogisticRegression(random_state=1)
>>> clf2 = RandomForestClassifier(random_state=1)
>>> clf3 = GaussianNB()
>>> eclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)], voting='soft')

>>> params = {'lr__C': [1.0, 100.0], 'rf__n_estimators': [20, 200],}

>>> grid = GridSearchCV(estimator=eclf, param_grid=params, cv=5)
>>> grid = grid.fit(iris.data, iris.target) 

用法

为了根据预测的类概率预测类标签(在VotingClassifier中必须支持scikit-learning估算器predict_proba):

>>> eclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)], voting='soft')
为了根据预测的类概率预测类标签(在VotingClassifier中必须支持scikit-learning估算器predict_proba):
>>> eclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)], voting='soft', weights=[2,5,1]) 
  • 无标签