引入
“三個臭皮匠賽過諸葛亮”——弱分類器組合成強分類器。
Q1.什麼是隨機森林?
隨機森林顧名思義就是一片森林,其中有各種各樣的樹,其實,隨機森林是基於決策樹構成的,一片森林中的每一顆樹就是一個決策樹。想了解決策樹算法詳情請戳☞決策樹原理及其實現☜
Q2.爲什麼叫隨機森林?
隨機森林中“隨機”一詞主要在於兩點:“隨機”取樣;“隨機”抽取特徵。
瞭解以上兩點,我們先從集成學習入手:
集成學習
的標準定義是:在原始數據上構建多個分類器,然後在分類未知樣本時聚集它們的預測結果。簡單理解就是:我們對多個訓練數據集構建不同的分類器
,再將這些分類器分別對測試集進行預測,將預測結果按照某種標準組合
起來。其中不同的分類器稱爲基分類器
,組合後的分類器稱爲組合分類器
。
而這種組合方法
最常見的有兩種:Bagging
,Boosting
。前者對不同數據集構建的基分類器之間相互獨立,也就是各自訓練各自的,互不影響。而後者基分類器的構成總是依賴於上一個分類器的分類結果,常見的Adaboost方法就是典型的boosting方法,下一個的分類器的構建依賴於上一次分類器錯分的樣本,總是對錯分的樣本給予更大的權重,(也就是說,下一次抽到上次分錯的樣本的可能性更大,對其不斷訓練)。bagging和Boosting方法的流程圖示如下:
bagging:
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()上下浮動,組合分類器誤差率爲: 可見,組合分類器的精度有着較大的提升。但是,是否每個分類器的組合都有此功效呢?不見得。在定義中,明確定義了“弱分類器”可組合成“強分類器”,那麼,什麼樣的分類器纔可成的上市“弱分類器”?一般,我們認爲,分類的錯誤率小於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爲例:
此時,準確率最高,達到70%
我們將10個分類器的分類結果進行組合:選擇多數表決的方法,即少數服從多數。得到組合分類器的分類結果和實際類一致,集成模型準確率達到100%。
隨機森林
本文討論的隨機森林算法就是基於bagging的方法,即對每個數據集建立差異性的Cart決策樹模型,將不同模型在測試集上的結果採取投票的方法進行整合。隨機森林在分類問題中使用分類樹,迴歸問題中使用迴歸樹。
隨機森林分類
隨機森林的步驟:
1、bootstrap抽取樣本子集;
2、每個樣本子集訓練一棵CART分類樹;
3、將每棵CART樹的分類結果進行投票,得到結果即爲隨機森林的預測。
第二個“隨機”——隨機抽取樣本子集
如果每個樣本的特徵維度爲M,指定一個常數m<<M,隨機地從M個特徵中選取m個特徵子集,每次樹進行分裂時,從這M個特徵中選擇最優的;每個節點都將隨機選擇m(m<M)個特定的變量,然後運用這m個變量來確定最佳的分裂點。在決策樹的生成過程中,m的值通常爲: or
注:每棵樹都盡最大程度的生長,並且沒有剪枝過程。
隨機森林迴歸
與分類不同在於:
1、目標變量是數值,模型評估指標爲:“MSE/MAE/”;分類爲:“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")