假設你去隨機問很多人一個很復雜的問題,然后把它們的答案合并起來。通常情況下你會發現這個合并的答案比一個專家的答案要好。這就叫做群體智慧。同樣的,如果你合并了一組分類器的預測(像分類或者回歸),你也會得到一個比單一分類器更好的預測結果。這一組分類器就叫做集成;因此,這個技術就叫做集成學習,一個集成學習算法就叫做集成方法。
例如,你可以訓練一組決策樹分類器,每一個都在一個隨機的訓練集上。為了去做預測,你必須得到所有單一樹的預測值,然后通過投票(例如第六章的練習)來預測類別。例如一種決策樹的集成就叫做隨機森林,它除了簡單之外也是現今存在的最強大的機器學習算法之一。
向我們在第二章討論的一樣,我們會在一個項目快結束的時候使用集成算法,一旦你建立了一些好的分類器,就把他們合并為一個更好的分類器。事實上,在機器學習競賽中獲得勝利的算法經常會包含一些集成方法。
在本章中我們會討論一下特別著名的集成方法,包括 bagging, boosting, stacking,和其他一些算法。我們也會討論隨機森林。
投票分類
假設你已經訓練了一些分類器,每一個都有 80% 的準確率。你可能有了一個邏輯斯蒂回歸、或一個 SVM、或一個隨機森林,或者一個 KNN,或許還有更多(詳見圖 7-1)
一個非常簡單去創建一個更好的分類器的方法就是去整合每一個分類器的預測然后經過投票去預測分類。這種分類器就叫做硬投票分類器(詳見圖 7-2)。
令人驚奇的是這種投票分類器得出的結果經常會比集成中最好的一個分類器結果更好。事實上,即使每一個分類器都是一個弱學習器(意味著它們也就比瞎猜好點),集成后仍然是一個強學習器(高準確率),只要有足夠數量的弱學習者,他們就足夠多樣化。
這怎么可能?接下來的分析將幫助你解決這個疑問。假設你有一個有偏差的硬幣,他有 51% 的幾率為正面,49% 的幾率為背面。如果你實驗 1000 次,你會得到差不多 510 次正面,490 次背面,因此大多數都是正面。如果你用數學計算,你會發現在實驗 1000 次后,正面概率為 51% 的人比例為 75%。你實驗的次數越多,正面的比例越大(例如你試驗了 10000 次,總體比例可能性就會達到 97%)。這是因為大數定律 :當你一直用硬幣實驗時,正面的比例會越來越接近 51%。圖 7-3 展示了始終有偏差的硬幣實驗。你可以看到當實驗次數上升時,正面的概率接近于 51%。最終所有 10 種實驗都會收斂到 51%,它們都大于 50%。
同樣的,假設你創建了一個包含 1000 個分類器的集成模型,其中每個分類器的正確率只有 51%(僅比瞎猜好一點點)。如果你用投票去預測類別,你可能得到 75% 的準確率!然而,這僅僅在所有的分類器都獨立運行的很好、不會發生有相關性的錯誤的情況下才會這樣,然而每一個分類器都在同一個數據集上訓練,導致其很可能會發生這樣的錯誤。他們可能會犯同一種錯誤,所以也會有很多票投給了錯誤類別導致集成的準確率下降。
如果使每一個分類器都獨立自主的分類,那么集成模型會工作的很好。去得到多樣的分類器的方法之一就是用完全不同的算法,這會使它們會做出不同種類的錯誤,這會提高集成的正確率
接下來的代碼創建和訓練了在 sklearn 中的投票分類器。這個分類器由三個不同的分類器組成(訓練集是第五章中的 moons 數據集):
>>> from sklearn.ensemble import RandomForestClassifier >>> from sklearn.ensemble import VotingClassifier >>> from sklearn.linear_model import LogisticRegression >>> from sklearn.svm import SVC>>> log_clf = LogisticRegression() >>> rnd_clf = RandomForestClassifier() >>> svm_clf = SVC()>>> voting_clf = VotingClassifier(estimators=[('lr', log_clf), ('rf', rnd_clf), >>> ('svc', svm_clf)],voting='hard') >>> voting_clf.fit(X_train, y_train)
讓我們看一下在測試集上的準確率:
>>> from sklearn.metrics import accuracy_score >>> for clf in (log_clf, rnd_clf, svm_clf, voting_clf): >>> clf.fit(X_train, y_train) >>> y_pred = clf.predict(X_test) >>> print(clf.__class__.__name__, accuracy_score(y_test, y_pred)) LogisticRegression 0.864 RandomForestClassifier 0.872 SVC 0.888 VotingClassifier 0.896
你看!投票分類器比其他單獨的分類器表現的都要好。
如果所有的分類器都能夠預測類別的概率(例如他們有一個predict_proba()方法),那么你就可以讓 sklearn 以最高的類概率來預測這個類,平均在所有的分類器上。這種方式叫做軟投票。他經常比硬投票表現的更好,因為它給予高自信的投票更大的權重。你可以通過把voting="hard"設置為voting="soft"來保證分類器可以預測類別概率。然而這不是 SVC 類的分類器默認的選項,所以你需要把它的probability hyperparameter設置為True(這會使 SVC 使用交叉驗證去預測類別概率,其降低了訓練速度,但會添加predict_proba()方法)。如果你修改了之前的代碼去使用軟投票,你會發現投票分類器正確率高達 91%
Bagging 和 Pasting
換句話說,Bagging 和 Pasting 都允許在多個分類器間對訓練集進行多次采樣,但只有 Bagging
就像之前講到的,可以通過使用不同的訓練算法去得到一些不同的分類器。另一種方法就是對每一個分類器都使用相同的訓練算法,但是在不同的訓練集上去訓練它們。有放回采樣被稱為裝袋(Bagging,是 bootstrap aggregating 的縮寫)。無放回采樣稱為粘貼(pasting)。
換句話說,Bagging 和 Pasting 都允許在多個分類器上對訓練集進行多次采樣,但只有 Bagging 允許對同一種分類器上對訓練集進行進行多次采樣。采樣和訓練過程如圖7-4所示。
當所有的分類器被訓練后,集成可以通過對所有分類器結果的簡單聚合來對新的實例進行預測。聚合函數通常對分類是統計模式(例如硬投票分類器)或者對回歸是平均。每一個單獨的分類器在如果在原始訓練集上都是高偏差,但是聚合降低了偏差和方差。通常情況下,集成的結果是有一個相似的偏差,但是對比與在原始訓練集上的單一分類器來講有更小的方差。
正如你在圖 7-4 上所看到的,分類器可以通過不同的 CPU 核或其他的服務器一起被訓練。相似的,分類器也可以一起被制作。這就是為什么 Bagging 和 Pasting 是如此流行的原因之一:它們的可擴展性很好。
在 sklearn 中的 Bagging 和 Pasting
sklearn 為 Bagging 和 Pasting 提供了一個簡單的API:BaggingClassifier類(或者對于回歸可以是BaggingRegressor。接下來的代碼訓練了一個 500 個決策樹分類器的集成,每一個都是在數據集上有放回采樣 100 個訓練實例下進行訓練(這是 Bagging 的例子,如果你想嘗試 Pasting,就設置bootstrap=False)。n_jobs參數告訴 sklearn 用于訓練和預測所需要 CPU 核的數量。(-1 代表著 sklearn 會使用所有空閑核):
>>>from sklearn.ensemble import BaggingClassifier >>>from sklearn.tree import DecisionTreeClassifier>>>bag_clf = BaggingClassifier(DecisionTreeClassifier(), n_estimators=500, >>>max_samples=100, bootstrap=True, n_jobs=-1) >>>bag_clf.fit(X_train, y_train) >>>y_pred = bag_clf.predict(X_test)
如果基分類器可以預測類別概率(例如它擁有predict_proba()方法),那么BaggingClassifier會自動的運行軟投票,這是決策樹分類器的情況。
圖 7-5 對比了單一決策樹的決策邊界和 Bagging 集成 500 個樹的決策邊界,兩者都在 moons 數據集上訓練。正如你所看到的,集成的分類比起單一決策樹的分類產生情況更好:集成有一個可比較的偏差但是有一個較小的方差(它在訓練集上的錯誤數目大致相同,但決策邊界較不規則)。
Bootstrap 在每個預測器被訓練的子集中引入了更多的分集,所以 Bagging 結束時的偏差比 Pasting 更高,但這也意味著預測因子最終變得不相關,從而減少了集合的方差。總體而言,Bagging 通常會導致更好的模型,這就解釋了為什么它通常是首選的。然而,如果你有空閑時間和 CPU 功率,可以使用交叉驗證來評估 Bagging 和 Pasting 哪一個更好。
Out-of-Bag 評價
對于 Bagging 來說,一些實例可能被一些分類器重復采樣,但其他的有可能不會被采樣。BaggingClassifier默認采樣。BaggingClassifier默認是有放回的采樣m個實例 (bootstrap=True),其中m是訓練集的大小,這意味著平均下來只有63%的訓練實例被每個分類器采樣,剩下的37%個沒有被采樣的訓練實例就叫做 Out-of-Bag 實例。注意對于每一個的分類器它們的 37% 不是相同的。
因為在訓練中分類器從來沒有看到過 oob 實例,所以它可以在這些實例上進行評估,而不需要單獨的驗證集或交叉驗證。你可以拿出每一個分類器的 oob 來評估集成本身。
在 sklearn 中,你可以在訓練后需要創建一個BaggingClassifier來自動評估時設置oob_score=True來自動評估。接下來的代碼展示了這個操作。評估結果通過變量oob_score_來顯示:
>>> bag_clf = BaggingClassifier(DecisionTreeClassifier(), n_estimators=500,bootstrap=True, n_jobs=-1, oob_score=True)>>> bag_clf.fit(X_train, y_train) >>> bag_clf.oob_score_ 0.93066666666666664
根據這個 obb 評估,BaggingClassifier可以再測試集上達到93.1%的準確率,讓我們修改一下:
>>> from sklearn.metrics import accuracy_score >>> y_pred = bag_clf.predict(X_test) >>> accuracy_score(y_test, y_pred) 0.93600000000000005
我們在測試集上得到了 93.6% 的準確率,足夠接近了!
對于每個訓練實例 oob 決策函數也可通過oob_decision_function_變量來展示。在這種情況下(當基決策器有predict_proba()時)決策函數會對每個訓練實例返回類別概率。例如,oob 評估預測第二個訓練實例有 60.6% 的概率屬于正類(39.4% 屬于負類):
>>> bag_clf.oob_decision_function_ array([[ 0., 1.], [ 0.60588235, 0.39411765],[ 1., 0. ], ... [ 1. , 0. ],[ 0., 1.],[ 0.48958333, 0.51041667]])
-
分類器
+關注
關注
0文章
152瀏覽量
13179 -
機器學習
+關注
關注
66文章
8406瀏覽量
132566 -
決策樹
+關注
關注
3文章
96瀏覽量
13548
原文標題:【翻譯】Sklearn 與 TensorFlow 機器學習實用指南 —— 第7章 集成學習和隨機森林(上)
文章出處:【微信號:AI_shequ,微信公眾號:人工智能愛好者社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論