機器學習進階 第一節 第十七課
阿新 • • 發佈:2020-12-15
技術標籤: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}