stacking是一種集成學(xué)習(xí)模型,主要利用分層模型搭建學(xué)習(xí)框架。
以兩層為例,第一層由多個(gè)基學(xué)習(xí)器組成,其輸入為原始訓(xùn)練集,第二層的模型則是以第一層基學(xué)習(xí)器的輸出作為特征加入訓(xùn)練集進(jìn)行再訓(xùn)練,從而得到完整的stacking模型。
stacking 模型具體是怎么操作的呢?
我們從這里拿來了一張圖并加上自己的理解來闡述stacking 的模型。



最后用一張圖來總結(jié)上面的過程

首先第一步是得到訓(xùn)練集與驗(yàn)證集(train_x,train_y,test_x,test_y),這里和普通的數(shù)據(jù)訓(xùn)練是一樣的。
對(duì)訓(xùn)練集的操作如下:
1.使用 KFold或者StratifiedKFold來對(duì)訓(xùn)練集進(jìn)行分割,將訓(xùn)練集的數(shù)據(jù)分割成n份。
值得注意的是StratifiedKFold 分層采樣交叉切分,確保訓(xùn)練集,測(cè)試集中各類別樣本的比例與原始數(shù)據(jù)集中相同,因此更加推薦使用StratifiedKFold
具體請(qǐng)參考KFold,StratifiedKFold k折交叉切分
2.隨機(jī)選擇其中的n-1份做為訓(xùn)練集中的訓(xùn)練集,剩下的1份作為訓(xùn)練集中的驗(yàn)證集,對(duì)訓(xùn)練集的訓(xùn)練集進(jìn)行fit,對(duì)訓(xùn)練集的測(cè)試機(jī)進(jìn)行predict 得到train_y_pred,同時(shí)對(duì)測(cè)試集pred,就得到test_y_pred,對(duì)得到的test_y_pred取平均值即輸出為最后的test_y_pred_mean
循環(huán)訓(xùn)練,就得到了n個(gè)test_y_pred_mean,將這n個(gè)test_y_pred_mean拼接起來,我們就得到了n_train_y_pred
循環(huán)訓(xùn)練,就得到了n個(gè)test_y_pred,對(duì)這n個(gè)test_y_pred求平均值
這樣第一步的融合訓(xùn)練就完成了
3.第二層模型,使用簡(jiǎn)單的模型,將第一層得到的結(jié)果進(jìn)行訓(xùn)練
首先將得到的n_train_y_pred 與 train_y 進(jìn)行訓(xùn)練
將得到的訓(xùn)練模型再對(duì)test_y_pred進(jìn)行預(yù)測(cè),就可以得到最終測(cè)試集的預(yù)測(cè)結(jié)果
更加細(xì)致一些的講解可以參考:https://blog.csdn.net/wstcjf/article/details/77989963
我們來看看具體是如何實(shí)現(xiàn)的
stacking 實(shí)現(xiàn)
import numpy as np
from sklearn.model_selection import KFold
#選擇from sklearn.model_selection import StratifiedKFold 也是可以的
def get_stacking(clf, x_train, y_train, x_test, n_folds=10):
#clf 訓(xùn)練的模型
#x_train 訓(xùn)練集x
#y_train 訓(xùn)練集y
#x_test 測(cè)試集x
#n_folds 訓(xùn)練集劃分
train_num, test_num = x_train.shape[0], x_test.shape[0]
second_level_train_set = np.zeros((train_num,)) #120*1
second_level_test_set = np.zeros((test_num,)) #30*1
test_nfolds_sets = np.zeros((test_num, n_folds)) #30*10
kf = KFold(n_splits=n_folds)
for i,(train_index, test_index) in enumerate(kf.split(x_train)):
x_tra, y_tra = x_train[train_index], y_train[train_index]
x_tst, y_tst = x_train[test_index], y_train[test_index]
clf.fit(x_tra, y_tra)
second_level_train_set[test_index] = clf.predict(x_tst)
test_nfolds_sets[:,i] = clf.predict(x_test)
second_level_test_set[:] = test_nfolds_sets.mean(axis=1)
return second_level_train_set, second_level_test_set
第一層模型融合
這里隨便選擇5種模型
from sklearn.ensemble import (RandomForestClassifier, AdaBoostClassifier,
GradientBoostingClassifier, ExtraTreesClassifier)
from sklearn.svm import SVC
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
#第一層的5個(gè)訓(xùn)練模型
model_1 = RandomForestClassifier()
model_2= AdaBoostClassifier()
model_3= GradientBoostingClassifier()
model_4= ExtraTreesClassifier()
model_5= SVC()
clfs=[model_1,model_2,model_3,model_4,model_5]
iris= load_iris() #導(dǎo)入鳶尾花數(shù)據(jù)集 150*4
train_x, test_x, train_y, test_y = train_test_split(iris.data, iris.target, test_size=0.3,random_state=2020)
#準(zhǔn)備工作已經(jīng)做好------->
#train_x 120*4
train_sets = []
test_sets = []
for clf in clfs:
train_set, test_set = get_stacking(clf, train_x, train_y, test_x)
train_sets.append(train_set)
test_sets.append(test_set)
meta_train = np.concatenate([result_set.reshape(-1,1) for result_set in train_sets], axis=1)
meta_test = np.concatenate([y_test_set.reshape(-1,1) for y_test_set in test_sets], axis=1)
第二層模型
#使用決策樹作為我們的次級(jí)分類器
from sklearn.tree import DecisionTreeClassifier
dt_model = DecisionTreeClassifier()
dt_model.fit(meta_train, train_y)
df_predict = dt_model.predict(meta_test)
參考:
https://blog.csdn.net/wqh_jingsong/article/details/77896449
https://www.cnblogs.com/jiaxin359/p/8559029.html
https://zhuanlan.zhihu.com/p/26890738
https://www.kaggle.com/arthurtok/introduction-to-ensembling-stacking-in-python
https://zhuanlan.zhihu.com/p/25836678