版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haiyu94/article/details/79400589
1. stacking原理
这里以2层stacking为例进行介绍
假设有3个基模型M1,M2, M3,
数据集:
- 划分数据集
- 第一层模型训练
为了防止过拟合,第一层采用k折验证得到第二层的输入,上图所示是五折交叉验证生成新的特征的过程,将训练集分成5份,每次选取其中4份使用模型M1进行学习,训练出的模型对另外1份进行预测得到 ,同时用改模型对测试集进行预测,其结果为 。进行五次训练之后,将五次得到的 组成完整的对训练集的预测结果,记为 ,对五次获得的测试集预测结果取平均得到新的测试集预测结果,记为
以此类推,对模型M2,模型M3使用同样的方法生成新的训练特征和测试特征 , ; , 生成新的训练集和测试集
将 , , 以及 , , 合并,得到新的训练集和测试集
, , —>( , , ),
, , —>( , , )第二层模型训练
使用第二层的模型M4对新的训练集进行学习,得到的模型对测试集进行预测,从而可以验证结果的准确性。
2. 代码实现
2.1 朴素代码
import numpy as np
from sklearn.model_selection import KFold
ntrain = train.shape[0]
ntest = test.shape[0]
kf = KFold(n_splits=5, random_state=2017)
def get_oof(clf, x_train, y_train, x_test):
oof_train = np.zeros((ntrain,))
oof_test = np.zeros((ntest,))
oof_test_skf = np.empty((5,ntest))
for i, (train_index, test_index) in enumerate(kf.split(x_train)):
kf_x_train = x_train[train_index]
kf_y_train = y_train[train_index]
kf_x_test = x_train[test_index]
clf.train(kf_x_train, kf_y_train)
oof_train[test_index] = clf.predict(kf_x_test)
oof_test_skf[i,:] = clf.predict(x_test)
oof_test[:] = oof_test_skf.mean(axis=0)
return oof_train.reshape(-1,1),oof_test.reshape(-1,1)
2.2 使用mlxtend库
from sklearn import datasets
iris = datasets.load_iris()
X,y = iris.data[:,1:3],iris.target
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from mlxtend.classifier import StackingClassifier
clf1 = KNeighborsClassifier(n_neighbors=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = GaussianNB()
lr = LogisticRegression()
sclf = StackingClassifier(classifiers=[clf1,clf2,clf3],meta_classifier=lr)
print('3-fold cross validation: \n')
for clf, label in zip([clf1,clf2,clf3,sclf],
['knn','random forest','naive bayes','stacking classifier']):
scores = model_selection.cross_val_score(clf, X, y, cv=3,scoring='accuracy')
print("Accuracy: %0.2f (+/- %0.2f) [%s]" %(scores.mean(),scores.std(), label))