機器學習——基於Bagging的集成學習:隨機森林(Random Forest)及python實現

引入

“三個臭皮匠賽過諸葛亮”——弱分類器組合成強分類器。

Q1.什麼是隨機森林?
隨機森林顧名思義就是一片森林,其中有各種各樣的樹,其實,隨機森林是基於決策樹構成的,一片森林中的每一顆樹就是一個決策樹。想了解決策樹算法詳情請戳☞決策樹原理及其實現
Q2.爲什麼叫隨機森林?
隨機森林中“隨機”一詞主要在於兩點:“隨機”取樣;“隨機”抽取特徵。
瞭解以上兩點,我們先從集成學習入手:
集成學習的標準定義是:在原始數據上構建多個分類器,然後在分類未知樣本時聚集它們的預測結果。簡單理解就是:我們對多個訓練數據集構建不同的分類器,再將這些分類器分別對測試集進行預測,將預測結果按照某種標準組合起來。其中不同的分類器稱爲基分類器,組合後的分類器稱爲組合分類器
而這種組合方法最常見的有兩種:BaggingBoosting。前者對不同數據集構建的基分類器之間相互獨立,也就是各自訓練各自的,互不影響。而後者基分類器的構成總是依賴於上一個分類器的分類結果,常見的Adaboost方法就是典型的boosting方法,下一個的分類器的構建依賴於上一次分類器錯分的樣本,總是對錯分的樣本給予更大的權重,(也就是說,下一次抽到上次分錯的樣本的可能性更大,對其不斷訓練)。bagging和Boosting方法的流程圖示如下:
bagging:
bagging
boosting:
boosting

Bagging裝袋

1、Bootstrap自助抽樣——“隨機”之一
Bagging爲Bootstrap aggregating直譯爲自助聚集算法,其中Bootstrap是一種自助抽樣方法,可以簡單的理解爲可重複抽樣。把bootstrap理解成每次取原數據集的一部分裝入一個袋中作爲一個子樣本,其特點是每次bootstrap結束後總會有一些樣本始終沒有被抽到,這些沒有被抽到的樣本稱爲OOB(Out Of Bag)
可以看到幾乎每一本機器學習教材都有涉及到“0.632採樣”,其中0.632代表的是原數據中總有63.2%的數據參與模型訓練,而剩餘的26.8%的樣本就是OOB樣本。
PS.OOB誤差:是指用全部數據進行訓練,其中63.2%的樣本訓練,剩下26.8%的樣本作爲測試集預測。
在這裏插入圖片描述
2、Bagging的優點
以單個決策樹爲基分類器,建立了25棵樹(基分類器),對任何一個樣本而言,平均或多數表決 原則下,當且僅當有13棵以上的樹判斷錯誤的時候,隨機森林纔會判斷錯誤。假設單獨一棵決策樹的錯誤率在0.35(ε\varepsilon)上下浮動,組合分類器誤差率爲:e=i=1325C25iεi(1ε)25i=0.06e=\sum_{i=13}^{25}C_{25}^i \varepsilon^i(1-\varepsilon)^{25-i}=0.06 可見,組合分類器的精度有着較大的提升。但是,是否每個分類器的組合都有此功效呢?不見得。在定義中,明確定義了“弱分類器”可組合成“強分類器”,那麼,什麼樣的分類器纔可成的上市“弱分類器”?一般,我們認爲,分類的錯誤率小於0.5的分類器爲弱分類器(可以思考,如果一個分類器錯誤率大於0.5,還不如隨機猜測來的好些,哪裏稱得上“弱”,此時大可說成“差”)也可通過python做圖如下:對於錯誤率小於0.5的分類器的組合效果遠超想象,下面我們通過一個例子更好的瞭解一下bagging的運作方式。
在這裏插入圖片描述

例:取《數據挖掘導論》5.4節的案例分別對比單個分類器和bagging組合分類器的效果:

x 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
y 1 1 1 -1 -1 -1 -1 1 1 1

對決策樹內容熟悉的小夥伴知道CART決策樹具有對連續屬性離散化的功能。主要方法步驟是:
1、對連續變量取值進行排序(本例已排序);
2、取每兩個數的中點爲閾值進行劃分(首尾自動±間隔/2);
3、計算每種劃分的gini係數,選取使gini值降低最多的閾值作爲分割點。
本文取k=10即抽取10個自助樣本,對每個樣本建立一個cart樹分類器,10個分類器的分類結果如下所示:

k x=0.1 x=0.2 x=0.3 x=0.4 x=0.5 x=0.6 x=0.7 x=0.8 x=0.9 x=1.0
1 1 1 1 -1 -1 -1 -1 -1 -1 -1
2 1 1 1 1 1 1 1 1 1 1
3 1 1 1 -1 -1 -1 -1 -1 -1 -1
8 -1 -1 -1 -1 -1 -1 -1 1 1 1
9 -1 -1 -1 -1 -1 -1 -1 1 1 1
10 1 1 1 1 1 1 1 1 1 1
2 2 2 -6 -6 -6 -6 2 2 2
組合分類器 1 1 1 -1 -1 -1 -1 1 1 1
實際類 1 1 1 -1 -1 -1 -1 1 1 1

以thres=0.35和thres=0.75爲例:
y={1,x0.351,x>0.35y'=\begin{cases} 1,x\leq 0.35\\ -1,x>0.35 \end{cases} y={1,x0.751,x>0.75y'=\begin{cases} -1,x\leq 0.75\\ 1,x>0.75 \end{cases}此時,準確率最高,達到70%
我們將10個分類器的分類結果進行組合:選擇多數表決的方法,即少數服從多數。得到組合分類器的分類結果和實際類一致,集成模型準確率達到100%。

隨機森林

本文討論的隨機森林算法就是基於bagging的方法,即對每個數據集建立差異性的Cart決策樹模型,將不同模型在測試集上的結果採取投票的方法進行整合。隨機森林在分類問題中使用分類樹,迴歸問題中使用迴歸樹。

隨機森林分類

隨機森林的步驟:
1、bootstrap抽取樣本子集;
2、每個樣本子集訓練一棵CART分類樹;
3、將每棵CART樹的分類結果進行投票,得到結果即爲隨機森林的預測。
第二個“隨機”——隨機抽取樣本子集
如果每個樣本的特徵維度爲M,指定一個常數m<<M,隨機地從M個特徵中選取m個特徵子集,每次樹進行分裂時,從這M個特徵中選擇最優的;每個節點都將隨機選擇m(m<M)個特定的變量,然後運用這m個變量來確定最佳的分裂點。在決策樹的生成過程中,m的值通常爲:m=sqrt(p)m = sqrt(p) or log(p)log(p)
注:每棵樹都盡最大程度的生長,並且沒有剪枝過程。

隨機森林迴歸

與分類不同在於:
1、目標變量是數值,模型評估指標爲:“MSE/MAE/R2R^2”;分類爲:“accuracy”
2、組合方法不同,迴歸爲:將所有基分類器的預測結果求平均;分類爲:投票

python實現

本例爲簡單實現,在真實數據集及完整調參參見:隨機森林實現及調參

隨機森林分類

0需要的庫

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline 
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_wine 
from sklearn.model_selection import train_test_split 
from sklearn.model_selection import cross_val_score 

1、 數據分割-紅酒數據

wine = load_wine()
x = wine.data
y = wine.target
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.3)

2、 建模

clf = DecisionTreeClassifier(random_state=18)
clf = clf.fit(xtrain,ytrain)
rf = RandomForestClassifier(random_state=18)
rf = rf.fit(xtrain,ytrain)
accuracy1 = clf.score(xtest,ytest)
accuracy2 = rf.score(xtest,ytest)
print("單個樹 :{}".format(accuracy1))
print("隨機森林 :{}".format(accuracy2))

3、 交叉驗證

rf_cv = cross_val_score(rf,x,y,cv=10)
clf_cv = cross_val_score(clf,x,y,cv=10)

plt.plot(range(1,11),rf_cv,label="RandomForest")
plt.plot(range(1,11),clf_cv,label="DecisionTree")
plt.legend()
plt.show()

4、 調參
(1) 確定最優樹個數

best_ntree = []
for i in range(1,200):
    rf = RandomForestClassifier(n_estimators=i+1,n_jobs=-1)
    rf_cv = cross_val_score(rf,x,y,cv=10).mean()
    best_ntree.append(rf_cv)
print(max(best_ntree),np.argmax(best_ntree)+1)

plt.figure(figsize=[20,5])
plt.plot(range(1,200),best_ntree)
plt.show()

(2) 袋外估計

rf = RandomForestClassifier(n_estimators=25)
rf = rf.fit(xtrain,ytrain)
score = rf.score(xtest,ytest)
score                     # 常規訓練集測試集

5、預測

rf.predict_proba(xtest)       # 預測概率
rf = RandomForestClassifier(n_estimators=20,random_state=18,oob_score=True)
rf = rf.fit(x, y)
rf.oob_score_

隨機森林迴歸

0、 導入庫

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import load_boston

1、 數據分割

boston = load_boston()
x = boston.data
y = boston.targe

2、 建模

rfr = RandomForestRegressor(n_estimators=100,random_state=18)

3、 模型評估

score = cross_val_score(rfr,x,y,cv=10,scoring="neg_mean_squared_error")
發佈了19 篇原創文章 · 獲贊 25 · 訪問量 3596
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章