機器學習-集成學習(ensemble learning)

集成學習ensemble learning:本身不是一個單獨的機器學習算法,而是通過構建並結合多個機器學習器來完成學習任務。
可以用兩句話形容:
1、“三個臭皮匠頂個諸葛亮”:一堆弱分類器的組合可以成爲一個強分類器;
2、“知錯能改,善莫大焉”:不斷在錯誤中學習,迭代來降低放錯概率。

投票分類器VotingClassifier:結合多個不同的機器學習分類器,使用多數票(hard)或者平均預測概率(soft)來預測數據標籤,可以平衡各個模型的弱點。

一、集成學習概述

1、訓練若干個個體學習器(弱學習器)
弱學習器可以是同質或異質的:
同質:boosting系列算法(一系列個體學習器存在強依賴關係,需要串行生成)
例如Ada(adaptive) Boosting算法 以及 提升樹Boosting系列算法,Gradient Boosting。
在這裏插入圖片描述

異質:bagging和隨機森林(Random Forest)(個體學習器間不存在強依賴關係,一系列個體學習器可以並行生成)。
在這裏插入圖片描述

區別bagging和boosting
在bagging方法中,特點在於隨機化抽樣,通過反覆的抽樣訓練新的模型,最終在這些模型的基礎上取平均。
boosting的核心思想在於,對多個模型的預測結果做加權平均則是將多個弱學習模型提升爲強學習模型,在此過程中權重在不斷更新。

2、一定的結合策略
在對個體學習器進行訓練後,需要一種結合策略,將其形成一個強學習器。
1)平均法:對若干個弱學習器的輸出進行平均(算術平均和加權平均等)得到最終的預測輸出,常用於數值類的迴歸預測問題。
2)投票法:相對多數投票法(少數服從多數)、絕對多數投票法(過半數票)以及加權投票法,常用於分類問題預測。
3)學習法:
爲了解決上述兩種方法學習誤差較大的問題,採用學習法,代表方法時stacking。
當使用stacking的結合策略時,會再加上一層學習器,此時弱學習器爲初級學習器,將用於結合的學習器稱爲次級學習器。對於測試集,我們首先用初級學習器預測一次,得到次級學習器的輸入樣本,再用次級學習器預測一次,得到最終的預測結果。

3、形成強學習器

二、AdaBoosting以及GBDT(Gradient Boosting Decision Tree)

這兩種算法是基於Boosting思想的著名算法,Boosting算法中,初始化時對每個訓練樣本賦予相等的權重,如1/n,然後利用該學習算法對訓練集訓練G輪,每次訓練後,對訓練失敗的訓練樣本進行學習,從而得到一個預測函數序列,預測效果好的預測函數權重較大。
而Adaboosting和GradientBoosting在面對已存在弱分類器組合的shortcomings時表徵不同,Adaboosting依據權值高的樣本點,而GrandientBoosting依據梯度

1)Adaboosting算法(記住兩點:兩個權重
涉及兩個權重的計算:
樣本的權值:
在沒有先驗知識的情況下,初始的分佈應爲等概分佈,樣本數目爲n,權值爲1/n;
每次迭代更新權值,提高分錯樣本的權重。
弱分類器的權值:
最後的強學習器是多個弱學習器通過權值組合得到的;
通過權值體現不同弱學習器的影響,正確率高的弱學習器權重高(實際上是分類誤差的一個函數)。

2)GradientBoosting算法(記住一點:梯度下降
GradientBoosting算法是一種利用樹的集成模型,引入損失函數描述模型的“靠譜”程度,假設模型未過擬合,損失函數越大,則模型錯誤率越高。
在求解損失函數時,可以通過梯度下降法來一步步迭代求解,得到最小化的損失函數和模型參數值(梯度即導數or偏導)。
GradientBoostingRegressor的函數參數如下(sklearn包中提供):

class sklearn.ensemble.GradientBoostingRegressor(
loss='ls', learning_rate=0.1, n_estimators=100, subsample=1.0, 
min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3,
init=None, random_state=None, max_features=None, alpha=0.9, 
verbose=0, max_leaf_nodes=None, warm_start=False, presort='auto')[source]

參數含義:
loss:選擇損失函數,默認值ls (least squres)
learning_rate:學習率,默認是0.1
n_estimators:弱學習器數目,默認是100
max_depth:每個學習器最大深度,限制迴歸樹的節點數目,默認是3
min_sample_split:可劃分內部節點的最小樣本數,默認是2
min_samples_leaf:葉節點所需的最小樣本數,默認是1.

篇外:理解梯度下降法(四步)
求梯度;相反方向移動x(引入步長概念);循環前一步,知道x變化使得f(x)在兩次迭代間差值足夠小;輸出x。
在這裏插入圖片描述

三、RandomForest以及ExtraTrees
隨機森林是ensemble方法中的bagging方法,用原始數據進行訓練至完全分裂最後得到多個決策樹,對新的數據的預測就是對所有的決策樹取平均值進行預測。ExtraTrees是bagging方法的一個修正版,使用訓練樣本直接構建隨機樹,由於RF和ExtraTrees區別較小,調參方法基本相同,接下來只介紹sklearn中RF的參數。
RandomForest關鍵概念

  • 採樣:樣本數量爲N,採樣數量也爲N,但是採取的是有放回的採樣bootstrap。
  • 訓練:決策樹完全分裂至所有的葉子節點,不做各種形式的剪枝,不需擔心overfiting問題。
  • 組合算法:訓練結束後,對新數據進行預測,會利用得到的M個決策樹對新數據進行預測,並對結果進行平均或者進行投票。sklearn算法是對各個樹進行平均取結果。
  • 分類和迴歸:隨機森林既可作分類,也可做迴歸,但主要是分類。

RandomForestClassifier的函數參數如下(sklearn包中提供):

class sklearn.ensemble.RandomForestClassifier(
n_estimators=10, criterion='gini', max_depth=None,min_samples_split=2, 
min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', 
max_leaf_nodes=None,bootstrap=True, oob_score=False, n_jobs=1,
random_state=None, verbose=0, warm_start=False, class_weight=None)[source]

參數含義:
n_estimators:森林中樹的個數,默認是10
criterion:衡量分類的質量,默認“gini”,即基尼不純度(Gini impurity),度量一個集合中每種類型的比例。支持規則有gini和entropy(信息增益)
max_features : int, float, string or None, optional (default=”auto”):需要考慮特徵的數目,If “auto”, then max_features=sqrt(n_features)
max_depth : integer or None, optional (default=None):樹最大深度
min_samples_split : integer, optional (default=2):分裂一個內部結點所需最少樣本數
min_samples_leaf : integer, optional (default=1):新創建輸液中最少樣本數
bootstrap=True:是否有放回的採樣。
oob_score : bool :oob(out of band,帶外)數據,即:在某次決策樹訓練中沒有被bootstrap選中的數據。多單個模型的參數訓練,我們知道可以用cross validation(cv)來進行,但是特別消耗時間,而且對於隨機森林這種情況也沒有大的必要,所以就用這個數據對決策樹模型進行驗證,算是一個簡單的交叉驗證。性能消耗小,但是效果不錯。
n_jobs=1:並行job個數。這個在ensemble算法中非常重要,尤其是bagging(而非boosting,因爲boosting的每次迭代之間有影響,所以很難進行並行化),因爲可以並行從而提高性能。1=不併行;n:n個並行;-1:CPU有多少core,就啓動多少job。
warm_start=False:熱啓動,決定是否使用上次調用該類的結果然後增加新的。
class_weight=None:各個label的權重。

四、投票分類器VotingClassifier
hard標準:相對多數投票

>>> from sklearn import datasets
>>> from sklearn.model_selection import cross_val_score
>>> from sklearn.linear_model import LogisticRegression
>>> from sklearn.naive_bayes import GaussianNB
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.ensemble import VotingClassifier
>>> iris = datasets.load_iris()
>>> X, y = iris.data[:, 1:3], iris.target
>>> clf1 = LogisticRegression(random_state=1)
>>> clf2 = RandomForestClassifier(random_state=1)
>>> clf3 = GaussianNB()
>>> eclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)], voting='hard')
>>> for clf, label in zip([clf1, clf2, clf3, eclf], ['Logistic Regression', 'Random Forest', 'naive Bayes', 'Ensemble']):
...     scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
...     print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))
Accuracy: 0.90 (+/- 0.05) [Logistic Regression]
Accuracy: 0.93 (+/- 0.05) [Random Forest]
Accuracy: 0.91 (+/- 0.04) [naive Bayes]
Accuracy: 0.95 (+/- 0.05) [Ensemble]

soft標準:返回預測概率值總和最大的標籤,可通過參數weights指定每個分類器的權重(此時將按照加權平均計算,標籤爲概率最高的)
例如:有3個分類器對一個結果進行預測,每個分類器權重爲w1=1,w2=1,w3=1。如下表中標籤2爲最終結果:
在這裏插入圖片描述

>>> from sklearn import datasets
>>> from sklearn.tree import DecisionTreeClassifier
>>> from sklearn.neighbors import KNeighborsClassifier
>>> from sklearn.svm import SVC
>>> from itertools import product
>>> from sklearn.ensemble import VotingClassifier
 
>>> # Loading some example data
>>> iris = datasets.load_iris()
>>> X = iris.data[:, [0,2]]
>>> y = iris.target
 
>>> # Training classifiers
>>> clf1 = DecisionTreeClassifier(max_depth=4)
>>> clf2 = KNeighborsClassifier(n_neighbors=7)
>>> clf3 = SVC(kernel='rbf', probability=True)
>>> eclf = VotingClassifier(estimators=[('dt', clf1), ('knn', clf2), ('svc', clf3)], voting='soft', weights=[2,1,2])
 
>>> clf1 = clf1.fit(X,y)
>>> clf2 = clf2.fit(X,y)
>>> clf3 = clf3.fit(X,y)
>>> eclf = eclf.fit(X,y)

VotingClassifier參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章