http://blog.csdn.net/willduan1/article/details/73618677
集成學習主要分為 bagging, boosting 和 stacking方法。本文主要是介紹stacking方法及其應用。但是在總結之前還是先回顧一下繼承學習。
這部分主要轉自知乎。
1. Bagging方法:
給定一個大小為n的訓練集 D,Bagging算法從中均勻、有放回地選出 m個大小為 n' 的子集Di,作為新的訓練集。在這 m個訓練集上使用分類、回歸等算法,則可得到 m個模型,再通過取平均值、取多數票等方法綜合產生預測結果,即可得到Bagging的結果。
(轉自知乎)
2. Boosting 方法
加入的過程中,通常根據它們的上一輪的分類准確率給予不同的權重。加和弱學習者之后,數據通常會被重新加權,來強化對之前分類錯誤數據點的分類,其中一個經典的提升算法例子是AdaBoost。
(來自知乎)
3. Stacking 方法:
將訓練好的所有基模型對整個訓練集進行預測,第j個基模型對第i個訓練樣本的預測值將作為新的訓練集中第i個樣本的第j個特征值,最后基於新的訓練集進行訓練。同理,預測的過程也要先經過所有基模型的預測形成新的測試集,最后再對測試集進行預測:
下面我們介紹一款功能強大的stacking利器,mlxtend庫,它可以很快地完成對sklearn模型地stacking。
主要有以下幾種使用方法吧:
I. 最基本的使用方法,即使用前面分類器產生的特征輸出作為最后總的meta-classifier的輸入數據
- 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
- import numpy as np
- 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',
- 'StackingClassifier']):
- 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))
II. 另一種使用第一層基本分類器產生的類別概率值作為meta-classfier的輸入,這種情況下需要將StackingClassifier的參數設置為 use_probas=True。如果將參數設置為 average_probas=True,那么這些基分類器對每一個類別產生的概率值會被平均,否則會拼接。
例如有兩個基分類器產生的概率輸出為:
classifier 1: [0.2, 0.5, 0.3]
classifier 2: [0.3, 0.4, 0.4]
1) average = True :
產生的meta-feature 為:[0.25, 0.45, 0.35]
2) average = False:
產生的meta-feature為:[0.2, 0.5, 0.3, 0.3, 0.4, 0.4]
- 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
- import numpy as np
- clf1 = KNeighborsClassifier(n_neighbors=1)
- clf2 = RandomForestClassifier(random_state=1)
- clf3 = GaussianNB()
- lr = LogisticRegression()
- sclf = StackingClassifier(classifiers=[clf1, clf2, clf3],
- use_probas=True,
- average_probas=False,
- meta_classifier=lr)
- print('3-fold cross validation:\n')
- for clf, label in zip([clf1, clf2, clf3, sclf],
- ['KNN',
- 'Random Forest',
- 'Naive Bayes',
- 'StackingClassifier']):
- 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))
III. 另外一種方法是對訓練基中的特征維度進行操作的,這次不是給每一個基分類器全部的特征,而是給不同的基分類器分不同的特征,即比如基分類器1訓練前半部分特征,基分類器2訓練后半部分特征(可以通過sklearn 的pipelines 實現)。最終通過StackingClassifier組合起來。
- from sklearn.datasets import load_iris
- from mlxtend.classifier import StackingClassifier
- from mlxtend.feature_selection import ColumnSelector
- from sklearn.pipeline import make_pipeline
- from sklearn.linear_model import LogisticRegression
- iris = load_iris()
- X = iris.data
- y = iris.target
- pipe1 = make_pipeline(ColumnSelector(cols=(0, 2)),
- LogisticRegression())
- pipe2 = make_pipeline(ColumnSelector(cols=(1, 2, 3)),
- LogisticRegression())
- sclf = StackingClassifier(classifiers=[pipe1, pipe2],
- meta_classifier=LogisticRegression())
- 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),用來設置上一個參數當使用概率值輸出的時候是否使用平均值。
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,最終的分類器只會使用基分類器產生的數據訓練。
屬性:
clfs_ : 每個基分類器的屬性,list, shape 為 [n_classifiers]。
meta_clf_ : 最終目標分類器的屬性
方法:
fit(X, y)
fit_transform(X, y=None, fit_params)
get_params(deep=True),如果是使用sklearn的GridSearch方法,那么返回分類器的各項參數。
predict(X)
predict_proba(X)
score(X, y, sample_weight=None), 對於給定數據集和給定label,返回評價accuracy
set_params(params),設置分類器的參數,params的設置方法和sklearn的格式一樣
------------------------------------------EOF---------------------------------
參考文獻:
https://zhihu.com/question/29036379/answer/111637662
https://rasbt.github.io/mlxtend/user_guide/classifier/StackingClassifier/
https://zh.wikipedia.org/zh-hans/Bagging%E7%AE%97%E6%B3%95
Wolpert, David H. "Stacked generalization." Neural networks 5.2 (1992): 241-259.