集成学习入门

论智2019-04-14 16:00:03
作者:Sagar Howal
编译:weakish

编者按:Towards Data Science博主Sagar Howal简明扼要地介绍了集成学习的常用技术。

使用多种不同的模型通常比使用单一模型更可靠。在单个数据集上使用多个协同工作的模型称为集成(Ensemble)。这一方法称为集成学习(Ensemble Learning)

投票

你可以使用多种不同的算法训练你的模型,然后加以集成以预测最终输出。比如,你可以使用随机森林分类器、SVM分类器、线性回归,等等。模型互相竞争,然后你可以使用sklearn.ensembleVotingClassifier类来挑选最佳表现。

硬投票(hard voting)按照简单多数原则选择最终预测。而软投票(soft voting)仅在所有的分类器都可以为输出计算概率时才可以使用。软投票通过对单独算法计算出的概率取均值得到最佳结果。

代码:

  1. from sklearn.svm import SVC

  2. from sklearn.linear_model import LogisticRegression

  3. from sklearn.ensemble import RandomForestClassifier

  4. from sklearn.ensemble import VotingClassifier

  5. log_clf = LogisticRegression()

  6. rnd_clf = RandomForestClassifier()

  7. svm_clf = SVC()

  8. voting_clf = VotingClassifier(

  9.    Estimators = [('lr', log_clf), ('rf', rnd_clf), ('svc',svm_clf)],

  10.    voting = 'hard')

  11. voting_clf.fit(X_train, y_train)

以上代码使用了SVM、线性回归、随机森林三种分类器,并进行硬投票。

一般而言,VotingClassifier的精确度比单独分类器要高。确保使用了差异足够大的分类器,这样类似的错误不会累积。

Bagging和Pasting

除了在单一数据集上运行多个模型以外,你还可以在一个数据集的多个随机子集上运行单个模型。有放回的随机取样称为Baggingbootstrap aggregaing,引导聚类)。如果这对你而言太不形象的话,你可以想像忽略数据集中的部分随机条目,然后基于剩下的条目建模。Pasting与此类似,只不过它不允许为同一预测反复取样训练实例。

代码:

  1. from sklearn.ensemble import BaggingClassifier

  2. from sklearn.tree import DecisionTreeClassifier

  3. bag_clf = BaggingClassifier(

  4.    DecisionTreeClassifier(random_state=42), n_estimators=500,

  5.    max_samples=100, bootstrap=True, n_jobs=-1, random_state=42)

  6. bag_clf.fit(X_train, y_train)

  7. y_pred = bag_clf.predict(X_test)

bootstrap=True参数指定使用Bagging。改为bootstrap=False则使用Pasting。

如果分类器可以计算预测概率,那么BaggingClassifier会自动进行软投票。可以计算预测概率的分类器带有predict_proba()方法。

一般而言,Bagging的结果比Pasting要好很多。

袋外验证

在训练集上使用Bagging时,模型只包括63%的实例,这意味着分类器看不到37%的实例。这些实例可以用于验证,类似交叉验证。

只需在之前的代码样例的BaggingClassifier类中加上oob_score = True参数即可使用这一功能。

代码:

  1. bag_clf = BaggingClassifier(

  2. DecisionTreeClassifier(random_state=42), n_estimators=500,

  3. max_samples=100, bootstrap=True, n_jobs=-1, random_state=42,

  4. oob_score = True)

目前我们取样的仅仅是实例。对具有大量特征的数据集而言,有其他的技术。

随机补丁和随机子空间

随机补丁同时取样训练实例和特征。在BaggingClassifier()中设定特定的参数即可使用:

  1. bootstrap_features = True, max_samples = 0.6

  2. # max_samples需小于1.0,否则会被舍弃

随机子空间保留所有样本,并取样特征:

  1. Bootstrap = True, bootstrap_features = True, max_features = 0.6

  2. # max_samples需小于1.0,否则会被舍弃


随机森林

集成决策树可得随机森林。随机森林内部进行Bagging操作。随机森林创建若干决策树,有时创建数千决策树,并为指定数据集计算可能最佳的模型。在分叉节点时,随机森林并不考虑所有特征,而是在所有特征的子集中选择最佳特征。这是用更高的偏置交换更低的差异,从而得到更好的模型。

代码:

  1. rom sklearn.ensemble import RandomForestClassifier

  2. rnd_clf = RandomForestClassifier(n_estimators=500, max_leaf_nodes=16, n_jobs=-1, random_state=42)

  3. rnd_clf.fit(X_train, y_train)

  4. y_pred_rf = rnd_clf.predict(X_test)

参数:

  • n_estimators是森林中的决策树数量限制。

  • max_leaf_nodes用于设置端节点的最大值,这样算法不会因为深深钻入单一特征而过拟合。

  • n_jobs指定使用的计算机核心数目。-1意味着使用所有的核心。

可以通过网格搜索变动参数的值以改善该模型。

AdaBoost

尽管AdaBoost技术的数学机制挺吓人的,它的理念还是很简单的。首先你选取一个基本分类器,在给定数据集上做出预测。记录错误分类的实例。然后增加错误分类的权重。第二个分类器基于更新的权重在训练集上进行训练。

简单来说,运行一个分类器并做出预测。运行另一个分类器拟合之前错误分类的实例并做出预测。重复此过程直到拟合所有/大部分训练实例。

AdaBoost不使用决策树,而使用决策树桩(Decision Stump),决策树桩可以看成max_depth = 1的决策树,即,由一个决策节点和两个叶节点组成的树。AdaBoost的n_estimators参数设定决策树桩的数目。

代码

  1. from sklearn.ensemble import AdaBoostClassifier

  2. ada_clf = AdaBoostClassifier(

  3.    DecisionTreeClassifier(max_depth=1), n_estimators=200,

  4.    algorithm="SAMME.R", learning_rate=0.5, random_state=42)

  5. ada_clf.fit(X_train, y_train)

Scikit-learn使用了Adaboost的多类版本,称为SAMME(多类指数损失函数逐步添加模型,Stagewise Additive Modelling using a Multiclass Exponential Loss Function)。如果预测器可以计算概率(具备predict_proba()方法),Scikit Learn使用SAMME.R(R代表实数),该算法基于概率,更不容易过拟合。

如果发生了过拟合,尝试正则化你的基本估计量。

梯度提升

类似AdaBoost,梯度提升同样基于加入集成的后续预测模型。和AdaBoost不同,梯度提升并不更新训练实例的权重,梯度提升让新模型去拟合残差。

简单来说,用一个模型拟合给定的训练集。计算残差,这些残差将成为新的训练实例,并在其之上训练一个新模型。所有模型相加以做出预测。

代码

  1. from sklearn.ensemble import GradientBoostingRegressor

  2. gbrt = GradientBoostingRegressor(max_depth=2, n_estimators=3, learning_rate=1.0, random_state=42)

  3. gbrt.fit(X, y)

学习率(learning_rate)参数收缩每棵树的分布。learning_raten_estimator需要折衷。降低learning_rate的值会增加集成中的树的数量。这称为收缩(Shrinkage)。注意,n_estimator过大可能导致过拟合。需要仔细监测这一折衷。

XGBoost

XGBoost是最近出现的、最受推崇的强大梯度提升方法。XGBoost不在叶节点处做出强硬的“是”和“否”决策,而是给每个做出的决定分配一个正值或负值。所有树都是一个弱学习者,提供比随机猜测稍好的决策。但将它们收集起来加以平均后,XGBoost表现非常好。

代码

  1. from xgboost import XGBoostClassifier

  2. xgb_clf = XGBClassifier()

  3. xgb_clf.fit(X, y)

XGBoost既可以配合树,也可以配合线性模型。推荐阅读XGBoost文档以获取更多参数调节选项。

XGBoost最近变得很流行,在大多数Kaggle竞赛优胜模型中得到使用。你的数据科学工具箱该有这么一个强大的工具。