談談模型融合之二 —— 隨機森林

前言

上篇文章介紹了集成學習的相關概念以及基於 Boosting的 AdaBoost,這篇文章將介紹基於模型融合的另外一種方式 Bagging 的算法,隨機森林(Random Forest)。(上篇公式敲的太累了這篇就來個簡單的緩解緩解)html

隨機森林

算法思想

咱們先來看看這個算法的名字,能夠拆分開爲兩部分,隨機和森林。森林咱們很容易能夠想到,就是有不少棵樹,即由多顆決策樹組成。那麼隨機指的是什麼呢?這裏咱們來看看 Bagging 的思想了。python

首先先說說自助採樣(Bootstrap Sanpling)算法

指任何一種有放回的均勻抽樣,也就是說,每當選中一個樣本,它等可能地被再次選中並被再次添加到訓練集中。app

而 Bagging 則是利用自助採樣獲得 T 組訓練樣本集,分別利用這些訓練樣本集訓練 T 個分類器,最後進行集成的方法。從 Bias-Variance 分解的角度看, Bagging 主要關注下降方差。dom

那麼,咱們大概就能知道這個隨機大概是什麼意思了,就是隨機抽取訓練集。學習

那麼,問題又來了,究竟是隨機抽取必定量的樣本呢仍是抽取部分特徵呢?答案是都有,隨機在這兩方面都有所體現。spa

因此能夠列出這麼一個等式—— Random Forest = Bagging + Fully-Grown CART with Random Subspace。rest

其特色爲:code

  1. 可高度並行化
  2. 繼承了 CART 的優勢
  3. 克服了徹底生長樹的缺點

融合策略

知道了隨機森林的算法思想後,知道了最後是須要將全部決策樹的預測結果進行集成,那咱們採用什麼方法進行集成呢?htm

大概有如下幾種方法:

  1. 平均法
  2. 加權平均法
  3. 投票法
    • 絕大多數投票(Majority Voting):超過半數則決策,不然拒絕
    • 少數服從多數(Plurality Voting):預測爲得票最多的標記法
  4. 學習法
    • 用各學習器的輸出生成新的訓練數據,再去訓練一個學習器

代碼實現

emmmmmmmmmmm。。。。忽然發現竟然沒有什麼數學推導????驚了

下面的代碼是基於投票法策略寫的

def bagging(X, y, T, size, seed=0, max_depth=None):
    """
    Bagging算法,分類器爲CART,用於二分類
    參數:
        X: 訓練集
        y: 樣本標籤
        T: T組
        size: 每組訓練集的大小
        seed: 隨機種子
        max_depth: 基學習器CART決策樹的最大深度
    返回:
        F: 生成的模型
    """
    classifiers = []
    m, n = X.shape
    
    np.random.seed(seed)
    for i in range(T):
        # 使用np.random.choice選擇size個序號,注意replace參數的設置,以知足有放回的均勻抽樣。
        index = np.random.choice(m,size)
        X_group = X[index]
        y_group = y[index]
        # 使用tree.DecisionTreeClassifier,設置max_depth=None, min_samples_split=2(生成徹底樹),random_state=0
        t = DecisionTreeClassifier(max_depth=max_depth, min_samples_split=2, random_state=0)
        # 開始訓練
#         print(y_group.shape)
        t.fit(X_group, y_group)
        classifiers.append(t)
    
    def F(X):
        # 計算全部分類器的預測結果
        result = []
        for t in classifiers:
            result.append(t.predict(X))
        # 把預測結果組成 num_X * T 的矩陣
        pred = np.vstack(result).T
        # 計算"0"有多少投票
        vote_0 = T - np.sum(pred, axis=1)
        # 計算"1"有多少投票
        vote_1 = np.sum(pred, axis=1)
        # 選擇投票數最多的一個標籤
        pred = (vote_1 > vote_0).astype(int)
        
        return pred     
    return F

小節

上篇的 AdaBoost 一堆公式推導,這就來了篇簡單的緩解緩解,寫着寫着發現就寫完了並且尚未公式的時候瞬間驚了,下篇該系列文章就來說講數據挖掘競賽中熟知的 GBDT

相關文章
相關標籤/搜索