天天看點

《scikit-learn》随機森林之分類預測乳腺癌模型

今天我們使用随機森林分類器來對乳腺癌資料進行預測

第一步:加載資料

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

from sklearn.datasets import load_breast_cancer  # 乳腺癌資料
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV, cross_val_score  # 網格搜尋,和交叉驗證名額

# 加載乳腺癌資料,569個樣本資料,30個屬性特征,次元不高,資料樣本也少。
breast_cancer = load_breast_cancer()
print(breast_cancer.data.shape)
print(breast_cancer.feature_names)
print(breast_cancer.target.shape)
print(breast_cancer.target_names)  # [“惡性”, “良性”]
# print(breast_cancer.keys())
           

第二步:簡單試驗一個随機森林的分類器的表現

# === 1: 單個随機森林的分類試驗
rfc = RandomForestClassifier(n_estimators=100, random_state=100) # 執行個體化
score = cross_val_score(rfc, breast_cancer.data, breast_cancer.target, cv=10, scoring='accuracy')
print("單個測試随機森林分類器的結果是:", score.mean())
           

第三步:利用學習曲線來調整調整一些參數,這裡我隻調整了n_estimators

使用交叉驗證。

# === 2: 使用學習曲線,來看看某些參數的影響,可以更能讓我們看到參數的影響趨勢。可以讓我們大緻能鎖定該參數最合适的取值範圍。
scores = []
for i in range(1, 201, 10):
    rfc = RandomForestClassifier(n_estimators=i, random_state=100, n_jobs=-1)
    score = cross_val_score(rfc, breast_cancer.data, breast_cancer.target, cv=10, scoring='accuracy').mean()
    scores.append(score)
print("最大的值是:{}, n_estimators的取值是{}.".format(max(scores), scores.index(max(scores)) * 10 + 1))
plt.figure(figsize=[10, 5])
plt.plot(range(1, 201, 10), scores)
plt.title("n_estimators")
plt.legend()
plt.show()
           

得到大緻的圖像如下:

《scikit-learn》随機森林之分類預測乳腺癌模型

發現在50~70之間存在峰值,那麼進一步利用學習曲線,縮小範圍來整。

# 經過學習曲線能夠觀察到,n_estimators 在50~60以後就趨于平穩了。在此處的地方可以達到最大
# 那麼而下一步,我們繼續細微調節,在最大值附近應該是存在某個很好的值
scores = []
for i in range(40, 70, 2):
    rfc = RandomForestClassifier(n_estimators=i, random_state=100, n_jobs=-1)
    score = cross_val_score(rfc, breast_cancer.data, breast_cancer.target, cv=10, scoring='accuracy').mean()
    scores.append(score)
print("最大的值是:{}, n_estimators的取值是{}.".format(max(scores), [*range(40, 70, 2)][scores.index(max(scores))] ))
plt.figure(figsize=[10, 5])
plt.plot(range(40, 70, 2), scores)
plt.title("n_estimators")
plt.legend()
plt.show()
# 前面的學習曲線,就是為給網格搜尋做準備的。知道了趨勢,友善更小範圍定位搜尋
           

曲線如下:

《scikit-learn》随機森林之分類預測乳腺癌模型

我們把多個參數一起這麼試驗。得到一些更小的範圍

最後我們根據不同的參數的小範圍來進行網格搜尋,對于範圍較大的參數建議一開始使用網格搜尋來看趨勢,鎖定小範圍。

# === 3: 使用網格搜尋
# 有一些參數,一上來我們根本不知道其範圍,範圍太大了,适合先用學習曲線來卡哪款趨勢。比如n_estimators 和 max_depth 和 max_leaf_nodes
# 有一些參數,可以知道範圍的,範圍也小,數量少,直接使用網格搜尋,比如criterion
clf = RandomForestClassifier(n_estimators=60, random_state=100, n_jobs=-1)
param_grid = [
    {'criterion': ['entropy', 'gini'],
     'max_features': [*range(10, 30, 2)],
     'max_depth': [5, 6, 7, 8, 9, 10],
     'min_samples_leaf': [*range(1, 10, 5)],
     'min_impurity_decrease': [*np.arange(0.01, 0.1, 0.01)]},  # 一共有 2x11x6x2x11 個超參數組合
]

grid_search = GridSearchCV(clf, param_grid, cv=10, n_jobs=2)
grid_search = grid_search.fit(breast_cancer.data, breast_cancer.target)

print(grid_search.best_params_)  # 找到最優的超參數,這裡幫我自動選擇好了最優的參數清單
print(grid_search.best_estimator_)  # 找到最優化的模型,甚至把初始化參數都列印出來了
print(grid_search.best_score_)  # 找到最優的結果