1. 程式人生 > 其它 >機器學習進階 第一節 第十七課

機器學習進階 第一節 第十七課

技術標籤:Pyhton 機器學習進階# Python 機器學習進階第一節

分類演算法之隨機森林

概述

在機器學習中, 隨機森林是一個包含多個決策樹的分類器. 並且其輸出的類別是由個別樹輸出的類別的眾數而定. 利用相同的訓練數搭建多個獨立的分類模型, 然後通過投票的方式, 以少數服從多數的原則作出最終的分類決策. 例如, 如果你訓練了 5 個樹, 其中有 4 個樹的結果是 True, 1 個樹的結果是 False, 那麼最終結果會是 True.

在前面的決策當中我們提到, 一個標準的決策樹會根據每維特徵對預測結果的影響程度進行排序. 進而決定不同的特徵從上至下構建分裂節點的順序. 如此一來, 所有在隨機森林中的決策樹都會受這一策略影響而構建的完全一致, 從而喪失的多樣性. 所以在隨機森林分類器的構建過程中, 每一棵決策樹都會放棄這一固定的排序演算法, 轉而隨機選取特徵.

學習演算法

根據下列演算法而建造每棵樹:

  • 用 N 來表示訓練用例 (樣本) 的個數, M 表示特徵數目
  • 輸入特徵數目 m, 用於確定決策樹上一個節點的決策結果. 其中 m 應遠小於 M
  • 從 N 個訓練用例 (樣本) 中以有放回抽樣的方式, 取樣 N 次, 形成一個訓練集 (即 bootstrap 取樣). 並用抽到的用例 (樣本) 做預測, 評估其誤差.
  • 對於每一個節點, 隨機選擇 m 個特徵, 決策樹上每個節點的決定都是基於這些特徵確定的. 根據這 m 個特徵, 計算其最佳的分類方式

sklearn.ensemble (整合方法模組)

sklearn.ensemble 提供了準確性更好的整合方法. 裡面包含了主要的 RandomForestClassifier (隨機森林) 方法.

class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, oob_score=False, n_jobs=1, random_state=None)
  """
  :param n_estimators:integer,optional(default = 10) 森林裡的樹木數量。

  :param criteria:string,可選(default =“gini”)分割特徵的測量方法

  :param max_depth:integer或None,可選(預設=無)樹的最大深度

  :param bootstrap:boolean,optional(default = True)是否在構建樹時使用自舉樣本。

  """

屬性

  • classes_ shape = [n_classes] 的陣列或者這樣的陣列列表, 類標籤 (單輸出問題) 或類標籤陣列列表 (多輸出問題)
  • featureimportances: array = [n_features] 的陣列, 特徵重要性 (越好, 功能越重要)

方法

  • fit (x, y[, sample_weight]) 從訓練集 (x, y): 構建一棵樹林
  • predict (x): 預測 X 的類
  • score(x, y[, sample_weight]): 返回給定測試資料和標籤的平均精度
  • decision_path (x) 返回森林中的決策路徑

泰坦尼克號乘客資料案例

此案例我們通過決策樹和隨機森林對這個資料進行一個分類, 判斷乘客的生還.

完整程式碼

import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import export_graphviz


def randomTree():
    """
    隨機森林對泰坦尼克號進行預測生死
    :return: None
    """

    # 獲取資料
    titan = pd.read_csv("titanic.csv")
    print(titan.head())

    # 處理資料, 找出特徵值和目標值
    x = titan[["Pclass", "Age", "Sex"]]
    y = titan["Survived"]

    # 缺失值處理
    x["Age"].fillna(x["Age"].mean(), inplace=True)

    # 分割資料集到訓練集合和測試集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)

    # 進行處理 (特徵工程)
    dict = DictVectorizer(sparse=False)
    x_train = dict.fit_transform(x_train.to_dict(orient="records"))
    x_test = dict.transform(x_test.to_dict(orient="records"))
    print(dict.get_feature_names())

    # 用隨機森林進行預測 (超引數調優)
    rf = RandomForestClassifier()
    param = {"n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30]}

    # 網格搜尋進行交叉驗證
    gc = GridSearchCV(rf, param_grid=param, cv=10)
    gc.fit(x_train, y_train)

    # 預測準確率
    print("預測的準確率: ", gc.score(x_test, y_test))
    print("最優準確率: ", gc.best_score_)
    print("檢視選擇引數模型: ", gc.best_params_)

    return None


if __name__ == "__main__":
    randomTree()

輸出結果:
預測的準確率:  0.7757847533632287
最優準確率:  0.8218562874251497
檢視選擇引數模型:  {'max_depth': 8, 'n_estimators': 300}