集成学习介绍之三——Stacking算法

2020-07-16  本文已影响0人  StataPython数据分析

本文作者:王 歌
文字编辑:戴 雯
技术总编:张 邯

通过前面的介绍我们知道集成学习是将多个基学习器结合在一起形成一个泛化性能更强的学习器来进行预测的,其中的Bagging和Boosting算法所选择的结合策略基本上是投票法、简单加和、简单平均、加权平均等方式。今天我们所介绍的Stacking算法则不同,它所使用的是“学习法”,下面我们具体来看看。

1算法原理

Stacking方法是一种分层模型集成框架。以两层为例,首先将数据集分成训练集和测试集,利用训练集训练得到多个初级学习器,然后用初级学习器对测试集进行预测,并将输出值作为下一阶段训练的输入值,最终的标签作为输出值,用于训练次级学习器(通常最后一级使用Logistic回归)。由于两次所使用的训练数据不同,因此可以在一定程度上防止过拟合。

由于要进行多次训练,因此这种方法要求训练数据很多,为了防止发生划分训练集和测试集后,测试集比例过小,生成的次级学习器泛化性能不强的问题,通常在Stacking算法中会使用我们上次讲到的交叉验证法或留一法来进行训练。

2算法实例

通过上面的介绍,大家对Stacking算法的思想也有了一个简单的了解,下面我们来看看如何实现。首先说一下我们今天要使用的库是mlxtend,在sklearn库中暂时还没有支持Stacking算法的类,所以在今天的例子中sklearn只能用来打辅助啦。mlxtend库是第三方库,可以通过pip install mlxtend直接安装即可。mlxtend兼容sklearn,可以组合sklearn生成的模型生成新的模型。我们今天使用的数据集是sklearn中的鸢尾花数据。

在mlxtend库中,如果实现分类算法,我们可以使用StackingClassifierStackingCVClassifier,如果实现回归算法可以使用StackingRegressorStackingCVRegressor,前者均为不使用交叉验证的Stacking算法,后者为使用交叉验证的Stacking算法,大家可以根据需要选择。这里我们使用StackingCVClassifier,它主要有以下参数:

(1)classifiers:选择基分类器,以列表的形式传入初级使用的模型,每个基分类器的属性可以查看类属性self._clfs_
(2)meta_classifier:确定目标分类器;
(3)use_probas:默认为False,当设置为True时,目标分类器的输入就是前面分类输出的类别概率值;
(4)average_probas:上一个参数当使用概率值输出的时候是否使用平均值,默认为False;
(5)verbose:控制使用过程中的日志输出,当verbose为0时不输出,verbose取1时输出回归器的序号和名字,verbose取2时输出详细的参数信息,verbose大于2时自动将verbose设置为小于2的值,默认为0;
(6)use_features_in_secondary:默认为False,当设置为True时,最终的目标分类器就由基分类器产生的数据和最初的数据集同时训练,若设置为False,最终的分类器只使用基分类器产生的数据训练;
(7)cv:设定交叉验证折数

这里我们使用的基分类器分别是<mark style="box-sizing: border-box;">SVM</mark>、<mark style="box-sizing: border-box;">决策树</mark>和<mark style="box-sizing: border-box;">GBDT</mark>,进行5折交叉验证,程序如下:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn import svm
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.linear_model import LogisticRegression
from mlxtend.classifier import StackingCVClassifier
from sklearn.metrics import accuracy_score
iris_sample = load_iris()
x = iris_sample.data
y = iris_sample.target
x_train, x_test, y_train, y_test = train_test_split(
    x, y, test_size=0.25, random_state=123)
svclf = svm.SVC(kernel='rbf', decision_function_shape='ovr', random_state=123)
treeclf = DecisionTreeClassifier()
gbdtclf = GradientBoostingClassifier(learning_rate=0.7)
lrclf = LogisticRegression()
scclf = StackingCVClassifier(
    classifiers=[svclf, treeclf, gbdtclf], meta_classifier=lrclf, cv=5)
scclf.fit(x_train, y_train)
scclf_pre = scclf.predict(x_test)
print('真实值:', y_test)
print('预测值:', scclf_pre)
print('准确度:', accuracy_score(scclf_pre, y_test))

我们这里首先保留了25%的数据不参与训练,作为最后验证结果的数据集,并将初级学习器svclftreeclfgbdtclf的参数设置为与前面的例子保持一致,最终得到的结果如下图:

image

在实际应用中,还可以通过调整初级学习器和次级学习器中参数的值来得到更好的效果。
Bagging、Boosting和Stacking都是目前集成学习中较为常用的算法,这三者各有所长,大家感兴趣可以进行更深入的研究。

上一篇下一篇

猜你喜欢

热点阅读