Stacking方法詳解


集成學習方法主要分成三種:bagging,boosting 和 Stacking。這里主要介紹Stacking。

 stacking嚴格來說並不是一種算法,而是精美而又復雜的,對模型集成的一種策略。

首先來看一張圖。

 

1、首先我們會得到兩組數據:訓練集和測試集。將訓練集分成5份:train1,train2,train3,train4,train5。

2、選定基模型。這里假定我們選擇了xgboost, lightgbm 和 randomforest 這三種作為基模型。比如xgboost模型部分:依次用train1,train2,train3,train4,train5作為驗證集,其余4份作為訓練集,進行5折交叉驗證進行模型訓練;再在測試集上進行預測。這樣會得到在訓練集上由xgboost模型訓練出來的5份predictions,和在測試集上的1份預測值B1。將這五份縱向重疊合並起來得到A1。lightgbm和randomforest模型部分同理。

3、三個基模型訓練完畢后,將三個模型在訓練集上的預測值作為分別作為3個"特征"A1,A2,A3,使用LR模型進行訓練,建立LR模型。

4、使用訓練好的LR模型,在三個基模型之前在測試集上的預測值所構建的三個"特征"的值(B1,B2,B3)上,進行預測,得出最終的預測類別或概率。

 做stacking,首先需要安裝mlxtend庫。安裝方法:進入Anaconda Prompt,輸入命令 pip install mlxtend 即可。

 stacking主要有幾種使用方法:

1、最基本的使用方法,即使用基分類器所產生的預測類別作為meta-classifier“特征”的輸入數據

 1 from sklearn import datasets
 2  
 3 iris = datasets.load_iris()
 4 X, y = iris.data[:, 1:3], iris.target
 5  
 6 from sklearn import model_selection
 7 from sklearn.linear_model import LogisticRegression
 8 from xgboost.sklearn import XGBClassifier
 9 import lightgbm as lgb
10 from sklearn.ensemble import RandomForestClassifier
11 from mlxtend.classifier import StackingClassifier
12 import numpy as np
13 
14 basemodel1 = XGBClassifier()
15 basemodel2 = lgb.LGBMClassifier()
16 basemodel3 = RandomForestClassifier(random_state=1)
17 
18 lr = LogisticRegression()
19 sclf = StackingClassifier(classifiers=[basemodel1, basemodel2, basemodel3], 
20                           meta_classifier=lr)
21  
22 print('5-fold cross validation:\n')
23  
24 for basemodel, label in zip([basemodel1, basemodel2, basemodel3, sclf], 
25                       ['xgboost', 
26                        'lightgbm', 
27                        'Random Forest',
28                        'StackingClassifier']):
29  
30     scores = model_selection.cross_val_score(basemodel,X, y, 
31                                               cv=5, scoring='accuracy')
32     print("Accuracy: %0.2f (+/- %0.2f) [%s]" 
33           % (scores.mean(), scores.std(), label))

2、這一種是使用第一層所有基分類器所產生的類別概率值作為meta-classfier的輸入。需要在StackingClassifier 中增加一個參數設置:use_probas = True。

另外,還有一個參數設置average_probas = True,那么這些基分類器所產出的概率值將按照列被平均,否則會拼接。

例如:

基分類器1:predictions=[0.2,0.2,0.7]

基分類器2:predictions=[0.4,0.3,0.8]

基分類器3:predictions=[0.1,0.4,0.6]

1)若use_probas = True,average_probas = True,

    則產生的meta-feature 為:[0.233, 0.3, 0.7]

2)若use_probas = True,average_probas = False,

    則產生的meta-feature 為:[0.2,0.2,0.7,0.4,0.3,0.8,0.1,0.4,0.6]

 1 from sklearn import datasets
 2  
 3 iris = datasets.load_iris()
 4 X, y = iris.data[:, 1:3], iris.target
 5  
 6 from sklearn import model_selection
 7 from sklearn.linear_model import LogisticRegression
 8 from xgboost.sklearn import XGBClassifier
 9 import lightgbm as lgb
10 from sklearn.ensemble import RandomForestClassifier
11 from mlxtend.classifier import StackingClassifier
12 import numpy as np
13  
14 basemodel1 = XGBClassifier()
15 basemodel2 = lgb.LGBMClassifier()
16 basemodel3 = RandomForestClassifier(random_state=1)
17 lr = LogisticRegression()
18 sclf = StackingClassifier(classifiers=[basemodel1, basemodel2, basemodel3], 
19                           use_probas=True,
20                           average_probas=False,
21                           meta_classifier=lr)
22 
23 print('5-fold cross validation:\n')
24 
25 for basemodel, label in zip([basemodel1, basemodel2, basemodel3, sclf], 
26                       ['xgboost', 
27                        'lightgbm', 
28                        'Random Forest',
29                        'StackingClassifier']):
30  
31     scores = model_selection.cross_val_score(basemodel,X, y, 
32                                               cv=5, scoring='accuracy')
33     print("Accuracy: %0.2f (+/- %0.2f) [%s]" 
34           % (scores.mean(), scores.std(), label))

3、這一種方法是對基分類器訓練的特征維度進行操作的,並不是給每一個基分類器全部的特征,而是賦予不同的基分類器不同的特征。比如:基分類器1訓練前半部分的特征,基分類器2訓練后半部分的特征。這部分的操作是通過sklearn中的pipelines實現。最終通過StackingClassifier組合起來。

 1 from sklearn.datasets import load_iris
 2 from mlxtend.classifier import StackingClassifier
 3 from mlxtend.feature_selection import ColumnSelector
 4 from sklearn.pipeline import make_pipeline
 5 from sklearn.linear_model import LogisticRegression
 6 from xgboost.sklearn import XGBClassifier
 7 from sklearn.ensemble import RandomForestClassifier
 8  
 9 iris = load_iris()
10 X = iris.data
11 y = iris.target
12 #基分類器1:xgboost
13 pipe1 = make_pipeline(ColumnSelector(cols=(0, 2)),
14                       XGBClassifier())
15 #基分類器2:RandomForest
16 pipe2 = make_pipeline(ColumnSelector(cols=(1, 2, 3)),
17                       RandomForestClassifier())
18  
19 sclf = StackingClassifier(classifiers=[pipe1, pipe2], 
20                           meta_classifier=LogisticRegression())
21  
22 sclf.fit(X, y)

 StackingClassifier使用API和參數說明:

StackingClassifier(classifiers, meta_classifier, use_probas=False, average_probas=False, verbose=0, use_features_in_secondary=False)
參數:
classifiers : 基分類器,數組形式,[cl1, cl2, cl3]. 每個基分類器的屬性被存儲在類屬性 self.clfs_.
meta_classifier : 目標分類器,即將前面分類器合起來的分類器
use_probas : bool (default: False) ,如果設置為True, 那么目標分類器的輸入就是前面分類輸出的類別概率值而不是類別標簽
average_probas : bool (default: False),當上一個參數use_probas = True時需設置,average_probas=True表示所有基分類器輸出的概率值需被平均,否則拼接。
verbose : int, optional (default=0)。用來控制使用過程中的日志輸出,當 verbose = 0時,什么也不輸出, verbose = 1,輸出回歸器的序號和名字。verbose = 2,輸出詳細的參數信息。verbose > 2, 自動將verbose設置為小於2的,verbose -2.
use_features_in_secondary : bool (default: False). 如果設置為True,那么最終的目標分類器就被基分類器產生的數據和最初的數據集同時訓練。如果設置為False,最終的分類器只會使用基分類器產生的數據訓練。
 
備注:Stacking一般多是兩層就夠了,多層也是可以的。
例如下圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM