1. 程式人生 > 實用技巧 >11-機器學習-隨機森林(bagging裝袋法的代表)

11-機器學習-隨機森林(bagging裝袋法的代表)

總結

隨機森林 (以決策樹為基學習器):

  • 隨機的體現
    • 資料集的隨機選擇:從原始資料集中採取有放回的抽樣bagging,構造子資料集。不同子資料集的元素可以重複,同一個子資料集中的元素也可以重複
    • 待選特徵的隨機選取:隨機森林中的子樹的每一個分裂過程並未用到所有的待選特徵,而是從所有的待選特徵中隨機選取一定的特徵,之後在隨機選取的特徵中選取最優的特徵
  • 隨機森林的重要作用
    • 分類問題和迴歸問題都能用
    • 可以解決模型過擬合的問題
    • 可以檢測出特徵的重要性
  • 隨機森林的構建過程
    • 1.從原始訓練集中隨機有放回取樣取出m個樣本,生成m個訓練集
    • 2.對m個訓練集,我們分別訓練m個決策樹模型
    • 3.對於單個決策樹模型,假設訓練樣本特徵的個數為n,那麼每次分裂時根據資訊增益/資訊增益比/基尼指數 選擇最好的特徵進行分裂
    • 4.將生成的多顆決策樹組成隨機森林。對於分類問題,按照多棵樹分類器投票決定最終分類結果;對於迴歸問題,由多顆樹預測值的均值決定最終預測結果
  • 隨機森林的優缺點
    • 優點
      • 1.精度高,準確性高
      • 2.不容易陷入過擬合(樣本隨機,特徵隨機)
      • 3具有一定的抗噪聲能力(不懼怕異常值)
      • 4.它能夠處理很高維度(feature標籤很多)的資料,並且不用做特徵選擇,對資料集的適應能力強:既能處理離散型資料,也能處理連續型資料
      • 5.在訓練過程中,能夠檢測到feature標籤間的互相影響,且可以得出feature的重要性,具有一定參考意義
    • 缺點
      • 1.當隨機森林中的決策樹個數很多時,訓練時需要的空間和時間會比較大(時間計算成本耗費較大)
  • API : from sklearn.ensemble import RandomForestClassifierfe(分類),RandomForestRegressor (迴歸)

隨機森林:是bagging裝袋法的代表。弱學習器只可以是決策樹

  • 簡介:
    • 隨機森林是一種有監督學習演算法,是以決策樹為基學習器的整合學習演算法。隨機森林非常簡單,易於實現,計算開銷也很小,在分類和迴歸上表現出非常驚人的效能,因此,隨機森林被譽為“代表整合學習技術水平的方法”。
  • 隨機森林的隨機性體現在哪幾個方面呢?
    • 1.資料集的隨機選擇
      • 從原始資料集中採取《有放回的抽樣bagging》,構造子資料集。不同子資料集的元素可以重複,同一個子資料集中的元素也可以重複。
    • 2.待選特徵的隨機選取
      • 隨機森林中的子樹的每一個分裂過程並未用到所有的待選特徵,而是從所有的待選特徵中隨機選取一定的特徵,之後再隨機選取的特徵中選取最優的特徵。
  • 隨機森林的重要作用:
    • 可以用於分類問題,也可以用於迴歸問題
    • 可以解決模型過擬合的問題,對於隨機森林來說,如果隨機森林中的樹足夠多,那麼分類器就不會出現過擬合
    • 可以檢測出特徵的重要性,從而選取好的特徵
  • 隨機森林的構建過程
    • 1.從原始訓練集中隨機有放回取樣取出m個樣本,生成m個訓練集
    • 2.對m個訓練集,我們分別訓練m個決策樹模型
    • 3.對於單個決策樹模型,假設訓練樣本特徵的個數為n,那麼每次分裂時根據資訊增益/資訊增益比/基尼指數 選擇最好的特徵進行分裂
    • 4.將生成的多顆決策樹組成隨機森林。對於分類問題,按照多棵樹分類器投票決定最終分類結果;對於迴歸問題,由多顆樹預測值的均值決定最終預測結果
  • 優點
    • 1.由於採用了整合演算法,本身精度比大多數單個演算法要好,所以準確性高
    • 2.由於兩個隨機性的引入,使得隨機森林不容易陷入過擬合(樣本隨機,特徵隨機)
    • 3.在工業上,由於兩個隨機性的引入,使得隨機森林具有一定的抗噪聲能力,對比其他演算法具有一定優勢
    • 4.它能夠處理很高維度(feature很多)的資料,並且不用做特徵選擇,對資料集的適應能力強:既能處理離散型資料,也能處理連續型資料
    • 5.在訓練過程中,能夠檢測到feature間的互相影響,且可以得出feature的重要性,具有一定參考意義
  • 缺點
    • 1.當隨機森林中的決策樹個數很多時,訓練時需要的空間和時間會比較大
  • 在sklearn.ensemble庫中,我們可以找到Random Forest分類和迴歸的實現:
    • API:from sklearn.ensemble import RandomForestClassifier,RandomForestRegressor
      • RandomForestClassifier # 分類
      • RandomForestRegression # 迴歸

控制弱評估器 (隨機森林為決策樹) 的引數

    

n_estimators(指定弱評估器數)

  • 這是森林中樹木的數量,即基評估器的數量。這個引數對隨機森林模型的精確性影響是單調的,n_estimators越大,模型的效果往往越好。但是相應的,任何模型都有決策邊界,n_estimators達到一定的程度之後,隨機森林的 精確性往往不在上升或開始波動,並且,n_estimators越大,需要的計算量和記憶體也越大,訓練的時間也會越來越 長。對於這個引數,我們是渴望在訓練難度和模型效果之間取得平衡。
  • n_estimators的預設值在現有版本的sklearn中是10,但是在即將更新的0.22版本中,這個預設值會被修正為 100。這個修正顯示出了使用者的調參傾向:要更大的n_estimators。

分類隨機森林RandomForestClassifier

  • 樹模型的優點是簡單易懂,視覺化之後的樹人人都能夠看懂,可惜隨機森林是無法被視覺化的。所以為了更加直觀地讓大家體會隨機森林的效果,我們來進行一個隨機森林和單個決策樹效益的對比。我們依然使用紅酒資料集。
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score

X = load_wine().data
y = load_wine().target
x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=2020)

# 邏輯迴歸
l = LogisticRegression(solver='liblinear').fit(x_train,y_train)  # solver為求解器
f1_score(y_test,l.predict(x_test),average='micro')  # 1.0

# 決策樹
d = DecisionTreeClassifier().fit(x_train,y_train)
f1_score(y_test,d.predict(x_test), average='micro')  # 0.9166666666666666

# 隨機森林
r = RandomForestClassifier().fit(x_train,y_train)
f1_score(y_test,r.predict(x_test),average='micro')  # 1.0

畫出隨機森林和決策樹在一組交叉驗證下的效果對比

%matplotlib inline
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt

rfc = RandomForestClassifier(n_estimators=25)
rfc_s = cross_val_score(rfc,wine.data,wine.target,cv=10)
clf = DecisionTreeClassifier()
clf_s = cross_val_score(clf,wine.data,wine.target,cv=10)
plt.plot(range(1,11),rfc_s,label = "RandomForest")
plt.plot(range(1,11),clf_s,label = "Decision Tree")
plt.legend()
plt.show()

畫出隨機森林和決策樹在十組交叉驗證下的效果對比

rfc_l = []
clf_l = []
for i in range(10):
    rfc = RandomForestClassifier(n_estimators=25)
    rfc_s = cross_val_score(rfc,wine.data,wine.target,cv=10).mean()
    rfc_l.append(rfc_s)
    clf = DecisionTreeClassifier()
    clf_s = cross_val_score(clf,wine.data,wine.target,cv=10).mean()
    clf_l.append(clf_s)
plt.plot(range(1,11),rfc_l,label = "Random Forest")
plt.plot(range(1,11),clf_l,label = "Decision Tree")
plt.legend()
plt.show()

隨機森林重要引數

random_state

  • 隨機森林中的random_state控制的是生成森林的模式,類似決策樹中的random_state,用來固定森林中樹的隨機性。當random_state固定時,隨機森林中生成是一組固定的樹。否則每次產生的樹會不一樣

bootstrap & oob_score

  • bootstrap (有放回抽樣):
    • 裝袋法是通過有放回的隨機抽樣技術來形成不同的訓練資料,bootstrap就是用來控制抽樣技術的引數。我們進行樣本的隨機取樣,每次取樣一個樣本,並在抽取下一個樣本之前將該樣本 放回原始訓練集,也就是說下次取樣時這個樣本依然可能被採集到。bootstrap引數預設True,代表採用這種有放回的隨機抽樣技術。通常,這個引數不會被我們設定為False。
  • oob_score (袋外資料做測試):
    • 然而有放回抽樣也會有自己的問題。由於是有放回,一些樣本可能會被採集多次,而其他一些樣本卻可能被忽略,一次都未被採集到。那麼這些被忽略或者一次都沒被採集到的樣本叫做oob袋外資料。
    • 也就是說,在使用隨機森林時,我們可以不劃分測試集和訓練集,只需要用袋外資料來測試我們的模型即可。
    • 如果希望用袋外資料來測試,則需要在例項化時就將oob_score這個引數調整為True,訓練完畢之後,我們可以用隨機森林的另一個重要屬性:oob_score_來檢視我們的在袋外資料上測試的結果:
# 無需劃分訓練集和測試集
rfc = RandomForestClassifier(n_estimators=25,oob_score=True)
rfc = rfc.fit(wine.data,wine.target)
# 重要屬性oob_score_ 
rfc.oob_score_  # 0.9662921348314607 多次執行分數會不一樣

迴歸隨機森林RandomForestRegressor

  • 所有的引數,屬性與介面,全部和隨機森林分類器一致。僅有的不同就是迴歸樹與分類樹的不同,不純度的指標, 引數Criterion不一致。
  • Criterion引數:
    • 迴歸樹衡量分枝質量的指標,支援的標準有三種:
      • 輸入"mse"使用均方誤差mean squared error(MSE),父節點和葉子節點之間的均方誤差的差額將被用來作為特徵選擇的標準,這種方法通過使用葉子節點的均值來最小化L2損失
      • 輸入“friedman_mse”使用費爾德曼均方誤差,這種指標使用弗裡德曼針對潛在分枝中的問題改進後的均方誤差
      • 輸入"mae"使用絕對平均誤差MAE(mean absolute error),這種指標使用葉節點的中值來最小化L1損失
from sklearn.ensemble import RandomForestRegressor  # 隨機森林的迴歸模型
from sklearn.tree import DecisionTreeRegressor  # 決策樹的迴歸模型
from sklearn.datasets import load_boston  # 波斯頓房價資料

X = load_boston().data
y = load_boston().target

x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=2020)

d = DecisionTreeRegressor(criterion='').fit(x_train,y_train)
d.score(x_test,y_test)  # 多次執行分數會不一樣 
0.6403035108402135

r = RandomForestRegressor().fit(x_train,y_train)
r.score(x_test,y_test)  # 多次執行分數會不一樣 
0.7424155489866165

進行又放回的隨機抽樣時,每一個弱評估器使用的訓練資料和原始樣本的訓練資料量級一致