機器學習演算法系列(十八)-隨機森林演算法(Random Forest Algorithm)

Saisimon發表於2022-02-23

閱讀本文需要的背景知識點:決策樹學習演算法、一丟丟程式設計知識

一、引言

  前面一節我們學習了一種簡單高效的演算法——決策樹學習演算法(Decision Tree Learning Algorithm),下面來介紹一種基於決策樹的整合學習1 演算法——隨機森林演算法2(Random Forest Algorithm)。

二、模型介紹

  有一個成語叫集思廣益,指的是集中群眾的智慧,廣泛吸收有益的意見。在機器學習演算法中也有類似的思想,被稱為整合學習(Ensemble learning)。

整合學習

  整合學習通過訓練學習出多個估計器,當需要預測時通過結合器將多個估計器的結果整合起來當作最後的結果輸出。

0.png
圖2-1

  圖2-1展示了整合學習的基本流程。

  整合學習的優勢是提升了單個估計器的通用性與魯棒性,比單個估計器擁有更好的預測效能。整合學習的另一個特點是能方便的進行並行化操作。

Bagging演算法

  Bagging演算法是一種整合學習演算法,其具體步驟為:假設有一個大小為 N 的訓練資料集,每次從該資料集中有放回的取選出大小為 M 的子資料集,一共選 K 次,根據這 K 個子資料集,訓練學習出 K 個模型。當要預測的時候,使用這 K 個模型進行預測,再通過取平均值或者多數分類的方式,得到最後的預測結果。

1.png
圖2-2

  圖2-2展示了Bagging演算法取子資料集的方法。

隨機森林演算法

  將多個決策樹結合在一起,每次資料集是隨機有放回的選出,同時隨機選出部分特徵作為輸入,所以該演算法被稱為隨機森林演算法。可以看到隨機森林演算法是以決策樹為估計器的Bagging演算法。

2.png
圖2-3

  圖2-3展示了隨機森林演算法的具體流程,其中結合器在分類問題中,選擇多數分類結果作為最後的結果,在迴歸問題中,對多個迴歸結果取平均值作為最後的結果。

  使用Bagging演算法能降低過擬合的情況,從而帶來了更好的效能。單個決策樹對訓練集的噪聲非常敏感,但通過Bagging演算法降低了訓練出的多顆決策樹之間關聯性,有效緩解了上述問題。

三、演算法步驟

  假設訓練集 T 的大小為 N ,特徵數目為 M ,隨機森林的大小為 K ,隨機森林演算法的具體步驟如下:

遍歷隨機森林的大小 K 次:

  從訓練集 T 中有放回抽樣的方式,取樣N 次形成一個新子訓練集 D

  隨機選擇 m 個特徵,其中 m < M

  使用新的訓練集 D 和 m 個特徵,學習出一個完整的決策樹

得到隨機森林

  上面演算法中 m 的選擇:對於分類問題,可以在每次劃分時使用根號M個特徵,對於迴歸問題, 選擇三分之 M 但不少於 5 個特徵。

四、優缺點

隨機森林演算法的優點:

  1. 對於很多種資料,可以產生高準確度的分類器
  2. 可以處理大量的輸入變數
  3. 可以在決定類別時,評估變數的重要性
  4. 在建造森林時,可以在內部對於一般化後的誤差產生不偏差的估計
  5. 包含一個好方法可以估計丟失的資料,並且如果有很大一部分的資料丟失,仍可以維持準確度
  6. 對於不平衡的分類資料集來說,可以平衡誤差
  7. 可被延伸應用在未標記的資料上,這類資料通常是使用非監督式聚類,也可偵測偏離者和觀看資料
  8. 學習過程很快速

隨機森林演算法的缺點:

  1. 犧牲了決策樹的可解釋性
  2. 在某些噪音較大的分類或迴歸問題上會過擬合
  3. 在多個分類變數的問題中,隨機森林可能無法提高基學習器的準確性

五、程式碼實現

使用 Python 實現隨機森林分類:

import numpy as np
from sklearn.tree import DecisionTreeClassifier

class rfc:
    """
    隨機森林分類器
    """

    def __init__(self, n_estimators = 100, random_state = 0):
        # 隨機森林的大小
        self.n_estimators = n_estimators
        # 隨機森林的隨機種子
        self.random_state = random_state

    def fit(self, X, y):
        """
        隨機森林分類器擬合
        """
        self.y_classes = np.unique(y)
        # 決策樹陣列
        dts = []
        n = X.shape[0]
        rs = np.random.RandomState(self.random_state)
        for i in range(self.n_estimators):
            # 建立決策樹分類器
            dt = DecisionTreeClassifier(random_state=rs.randint(np.iinfo(np.int32).max), max_features = "auto")
            # 根據隨機生成的權重,擬合資料集
            dt.fit(X, y, sample_weight=np.bincount(rs.randint(0, n, n), minlength = n))
            dts.append(dt)
        self.trees = dts

    def predict(self, X):
        """
        隨機森林分類器預測
        """
        # 預測結果陣列
        probas = np.zeros((X.shape[0], len(self.y_classes)))
        for i in range(self.n_estimators):
            # 決策樹分類器
            dt = self.trees[i]
            # 依次預測結果可能性
            probas += dt.predict_proba(X)
        # 預測結果可能性取平均
        probas /= self.n_estimators
        # 返回預測結果
        return self.y_classes.take(np.argmax(probas, axis = 1), axis = 0)

使用 Python 實現隨機森林迴歸:

import numpy as np
from sklearn.tree import DecisionTreeRegressor

class rfr:
    """
    隨機森林迴歸器
    """

    def __init__(self, n_estimators = 100, random_state = 0):
        # 隨機森林的大小
        self.n_estimators = n_estimators
        # 隨機森林的隨機種子
        self.random_state = random_state

    def fit(self, X, y):
        """
        隨機森林迴歸器擬合
        """
        # 決策樹陣列
        dts = []
        n = X.shape[0]
        rs = np.random.RandomState(self.random_state)
        for i in range(self.n_estimators):
            # 建立決策樹迴歸器
            dt = DecisionTreeRegressor(random_state=rs.randint(np.iinfo(np.int32).max), max_features = "auto")
            # 根據隨機生成的權重,擬合資料集
            dt.fit(X, y, sample_weight=np.bincount(rs.randint(0, n, n), minlength = n))
            dts.append(dt)
        self.trees = dts

    def predict(self, X):
        """
        隨機森林迴歸器預測
        """
        # 預測結果
        ys = np.zeros(X.shape[0])
        for i in range(self.n_estimators):
            # 決策樹迴歸器
            dt = self.trees[i]
            # 依次預測結果
            ys += dt.predict(X)
        # 預測結果取平均
        ys /= self.n_estimators
        return ys

六、第三方庫實現

scikit-learn3 實現隨機森林分類:

from sklearn.ensemble import RandomForestClassifier

# 隨機森林分類器
clf = RandomForestClassifier(n_estimators = 100, random_state = 0)
# 擬合資料集
clf = clf.fit(X, y)

scikit-learn4 實現隨機森林迴歸:

from sklearn.ensemble import RandomForestRegressor

# 隨機森林迴歸器
clf = RandomForestRegressor(n_estimators = 100, random_state = 0)
# 擬合資料集
clf = clf.fit(X, y)

七、動畫演示

  圖7-1、圖7-2分別展示了使用隨機森林演算法進行分類與迴歸的結果,圖7-3、圖7-4分別展示了上一節中使用決策學習演算法進行分類與迴歸的結果。可以看到對比上一節中單獨未正則化的決策樹,其預測的結果相對更加平穩一些。

3.png
圖7-1

4.png
圖7-2

14.png
圖7-3

16.png
圖7-4

八、思維導圖

5.jpeg
圖8-1

九、參考文獻

  1. https://en.wikipedia.org/wiki...
  2. https://en.wikipedia.org/wiki...
  3. https://scikit-learn.org/stab...
  4. https://scikit-learn.org/stab...

完整演示請點選這裡

注:本文力求準確並通俗易懂,但由於筆者也是初學者,水平有限,如文中存在錯誤或遺漏之處,懇請讀者通過留言的方式批評指正

本文首發於——AI導圖,歡迎關注

相關文章