stacking模型融合_关于Stacking模型融合及源码分享

Stacking是用新的模型(次学习器)去学习怎么组合那些基学习器,它的思想源自于Stacked Generalization(http://www.machine-learning.martinsewell.com/ensembles/stacking/Wolpert1992.pdf)这篇论文。如果把Bagging看作是多个基分类器的线性组合,那么Stacking就是多个基分类器的非线性组合。Stacking可以很灵活,它可以将学习器一层一层地堆砌起来,形成一个网状的结构,如下图:

30414d8c81e9793ad75c150d6eca2d92.png

举个更直观的例子,还是那两道加法题:

75294360cc0b6c004e599cd67b29f81d.png

这里A和B可以看作是基学习器,C、D、E都是次学习器。

· Stage1: A和B各自写出了答案。

· Stage2: C和D偷看了A和B的答案,C认为A和B一样聪明,D认为A比B聪明一点。他们各自结合了A和B的答案后,给出了自己的答案。

Stage3: E偷看了C和D的答案,E认为D比C聪明,随后E也给出自己的答案作为最终答案。

在实现Stacking时,要注意的一点是,避免标签泄漏(Label Leak)。在训练次学习器时,需要上一层学习器对Train Data的测试结果作为特征。如果我们在Train Data上训练,然后在Train Data上预测,就会造成Label Leak。为了避免Label Leak,需要对每个学习器使用K-fold,将K个模型对Valid Set的预测结果拼起来,作为下一层学习器的输入。如下图:

a3bfc02c8cda4ce74534c422eef00c2d.png

由图可知,我们还需要对Test Data做预测。这里有两种选择,可以将K个模型对Test Data的预测结果求平均,也可以用所有的Train Data重新训练一个新模型来预测Test Data。所以在实现过程中,我们最好把每个学习器对Train Data和对Test Data的测试结果都保存下来,方便训练和预测。

对于Stacking还要注意一点,固定K-fold可以尽量避免Valid Set过拟合,也就是全局共用一份K-fold,如果是团队合作,组员之间也是共用一份K-fold。如果想具体了解为什么需要固定K-fold,

举个例子,假设训练数据一共有x1, x2, x3, x4, x5, x6这6个,并且使用3-fold,在Stage1的时候使用两个Model。

1. 使用固定的k-fold的情况如下图:

4a789efbd3b02a60671953ec7cac152f.png

先看Stage1:可以看到m1-m6和n1-n2是相同的k-fold预测出来的结果,m1,m2由x3,x4,x5,x6预测所得,所以m1,m2包含了x3,x4,x5,x6的信息,以此类推。

Stage2:假设我要用如图中所示的Train Set来预测Valid Set,那么Train Set包含了x1-x6的信息,而Valid Set包含了x3-x6的信息。

看到这里你会疑惑,这有什么用呢?别急,再来看看Stage1的两个Model各自用不同的k-fold:

c8e26a82e2b525df87d06f69b04692a9.png

请仔细观察Model2的k-fold,现在n1,n6包含了x2-x5的信息,以此类推。

关键在于Stage2,现在Train Set也是包含了x1-x6的信息,而Valid Set也包含了x1-x6的信息,这就是不固定kfold与固定kfold的区别。尽管从固定kfold的图看来,它也有可能出现一定程度的过拟合,但不固定kfold它对Valid Set的过拟合情况会更加严重,所以按照Nutastray说的,通过kfold可以避免人为造成的过拟合。

可能你会问,那如果我们同一层的Stage固定k-fold,而不同层之间不固定,会发生什么?答案是,情况也会比固定k-fold要糟糕,具体的话可以按照上图画一下。所以最终给出的建议是,做Stacking最好还是固定k-fold,如果是团队合作完成项目,那就组员之间共享一份k-fold。

下面给出我的代码:bb=data_train.iloc[:, 4:6749]

#dd=data_train.iloc[:, 3:4]

cc = bb.apply(lambda x: x.fillna(x.mean()), axis=0)

x_data = preprocessing.minmax_scale(cc.iloc[:, :].values, feature_range=(-1,1))

cc['tag'] = data_train.iloc[:, 3:4]

test = dfp.iloc[:, 2:6747].apply(lambda x: x.fillna(x.mean()), axis=0)

#test_data = preprocessing.minmax_scale(test.iloc[:, :].values, feature_range=(-1,1))

Xtest = list(test.columns.values)[4:6745]

x_data_output = dfp.iloc[:, 0:1].values

#print(data_train.iloc[:, 3:4])

predictors = list(cc.columns.values)[4:6745]

alg1 = lgb.LGBMClassifier(boosting_type='gbdt', num_leaves=42, max_depth=-1, learning_rate=0.054, n_estimators=490,

subsample_for_bin=200, objective='binary', class_weight=None, min_split_gain=0.0,

min_child_weight=1, min_child_samples=21, subsample=0.72, subsample_freq=1,

colsample_bytree=0.63, reg_alpha=6.18, reg_lambda=2.718, random_state=142857, n_jobs=-1,

silent=True, importance_type='split')

alg2 = XGBClassifier(n_estimators=60,max_depth=9,min_child_weight=2,gamma=0.9,subsample=0.8,learning_rate=0.02,

colsample_bytree=0.8,objective='binary:logistic',nthread=-1,scale_pos_weight=1)

alg3 = GradientBoostingClassifier(learning_rate=0.01, n_estimators=600, max_depth=7, min_samples_leaf=60,

min_samples_split=1200, max_features=9, subsample=0.7, random_state=10)

lr = LogisticRegression()

pipe1 = make_pipeline(ColumnSelector(cols=predictors[4:2000]), lr)

pipe2 = make_pipeline(ColumnSelector(cols=predictors[2000:4000]), alg2)

pipe3 = make_pipeline(ColumnSelector(cols=predictors[4000:5000]), alg3)

sclf = StackingClassifier(classifiers=[lr, pipe2, pipe3], meta_classifier=alg1)

# Compute the accuracy score for all the cross validation folds. (much simpler than what we did before!)

# kf=cross_validation.KFold(data_train.shape[0],n_folds=10,random_state=1)

kf = model_selection.KFold(n_splits=120, shuffle=False, random_state=1)

scores = model_selection.cross_val_score(sclf, cc[predictors], cc['tag'], cv=kf)

print("scores.mean=

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值