1. 程式人生 > 其它 >@[機器學習應用篇:隨機森林]

@[機器學習應用篇:隨機森林]

技術標籤:機器學習資料探勘

(機器學習演算法應用篇:隨機森林)

引言

前段時間做國創專案,用到了隨機森林演算法,今天來總結一下相關知識以及實現過程。

一.隨機森林的基礎知識

1.資訊,熵,資訊增益:
1)資訊:對機器學習中的決策樹而言,如果帶分類的事物集合可以劃分為多個類別當中,則某個類(xi)的資訊可以定義如下
在這裡插入圖片描述
2)熵:熵是用來度量不確定性的,當熵越大,X=xi的不確定性越大,反之越小。

3)資訊增益:資訊增益在決策樹演算法中是用來選擇特徵的指標,資訊增益越大,則這個特徵的選擇性越好

2.自助法(bootstrap):自助法顧名思義,即從樣本自身中再生成很多可用的同等規模的新樣本,從自己中產生和自己類似的,所以叫做自助,即不借助其他樣本資料。

3.自整合(bagging):bagging方法將訓練集分成m個新的訓練集,然後在每個新訓練集上構建一個模型,各自不相干,最後預測時我們將這個m個模型的結果進行整合,得到最終結果。

4.決策樹(Decision Tree):決策樹是用樹的結構來構建分類模型,每個節點代表著一個屬性,常用的決策樹有ID4,C4.5,CART等,可以用資訊增益,增益率,以及基尼係數等指標來衡量選取。

5.隨機森林(Random Forest):簡單來說,隨機森林就是用bootstrap方法生成m個訓練集,然後,對於每個訓練集,構造一顆決策樹,在節點找特徵進行分裂的時候,在特徵中隨機抽取一部分特徵,在抽到的特徵中間找到最優解,應用於節點,進行分裂。隨機森林的方法由於有了bagging

,也就是整合的思想在,實際上相當於對於樣本和特徵都進行了取樣(如果把訓練資料看成矩陣,就像實際中常見的那樣,那麼就是一個行和列都進行取樣的過程),所以可以避免過擬合。

二. 隨機森林和決策樹的生成過程

1.樹:如果訓練集大小為N,對於每棵樹而言,隨機且有放回地從訓練集中的抽取N個訓練樣本,作為該樹的訓練集。
問題1:為什麼要隨機抽樣訓練集?
如果不進行隨機抽樣,每棵樹的訓練集都一樣,那麼最終訓練出的樹分類結果也是完全一樣的。
問題2:為什麼要有放回地抽樣?
如果不是有放回的抽樣,那麼每棵樹的訓練樣本都是不同的,每棵樹訓練出來可能有很大的差異。

2.隨機森林:
1)從原始訓練集中使用Bootstraping

方法隨機有放回取樣選出m個樣本,共進行n_tree次取樣,生成n_tree個訓練集
2)對於n_tree個訓練集,我們分別訓練n_tree個決策樹模型
3)對於單個決策樹模型,假設訓練樣本特徵的個數為n,那麼每次分裂時根據資訊增益/資訊增益比/基尼指數選擇最好的特徵進行分裂
4)每棵樹都一直這樣分裂下去,直到該節點的所有訓練樣例都屬於同一類。在決策樹的分裂過程中不需要剪枝
5)將生成的多棵決策樹組成隨機森林。對於分類問題,按多棵樹分類器投票決定最終分類結果;對於迴歸問題,由多棵樹預測值的均值決定最終預測結果.

三.隨機森林程式碼的實現

專案中用到的是隨機森林預測演算法,所以程式碼是基於預測的。
需要匯入的包(py3)


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import csv
import random
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import RandomizedSearchCV
from sklearn.metrics import mean_squared_error, explained_variance_score,mean_absolute_error,r2_score

1.資料集的劃分
資料集一般劃分為訓練集和測試集,用到了train_test_split函式。

#資料處理,將有效的標籤值提取出來,賦值給data
data = data.loc[:, ~data.columns.str.contains('Unnamed')]
#劃分測試集和訓練集,test_size為測試集佔比
data_train,data_test=train_test_split(data,test_size=0.1,random_state=1)

2.模型引數的選擇

	 criterion=['mae','mse'] 
   n_estimators = [int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)]
   max_features = ['auto', 'sqrt']
   max_depth = [int(x) for x in np.linspace(10, 100, num = 10)]
   max_depth.append(None)
   min_samples_split = [2, 5, 10]
   min_samples_leaf = [1, 2, 4]
   bootstrap = [True, False]
   random_grid = {'criterion':criterion,
              'n_estimators': n_estimators,
              'max_features': max_features,
              'max_depth': max_depth,
              'min_samples_split': min_samples_split,
              'min_samples_leaf': min_samples_leaf,
              'bootstrap': bootstrap}

3.構建模型

clf= RandomForestRegressor()
clf_random = RandomizedSearchCV(estimator=clf, param_distributions=random_grid,
                         		n_iter = 50,  
                                cv = 5, verbose=2, random_state=42, n_jobs=-1)

4.最優引數選取

clf_random.fit(X_train,y_train)
print (clf_random.best_params_)

5.模型訓練、驗證和評估

rf=RandomForestRegressor(criterion='mse',bootstrap=False,max_features='sqrt', max_depth=20,min_samples_split=10,   n_estimators=1200,min_samples_leaf=2)
rf.fit(X_train,y_train)
y_train_pred=rf.predict(X_train)
y_test_pred=rf.predict(X_test)

print("Decision tree model evaluation -- training set:") #決策樹模型評估--訓練集
print('trainr^2:',rf.score(X_train,y_train))#訓練r^2
print('Mean square deviation:',mean_squared_error(y_train,y_train_pred))#均方差
print('Absolute difference:',mean_absolute_error(y_train,y_train_pred))#絕對差
print('Degree of interpretation',explained_variance_score(y_train,y_train_pred))#解釋度
print("Decision tree model evaluation -- Verification set:")#決策樹模型評估--驗證集
print('verificationr^2:',rf.score(X_test,y_test))#驗證r^2
print('Mean square deviation',mean_squared_error(y_test,y_test_pred))#均方差
print('Absolute difference',mean_absolute_error(y_test,y_test_pred))#絕對差
print('Degree of interpretation',explained_variance_score(y_test,y_test_pred))#解釋度

6.引數解釋
1)n_estimators:森林中數的個數。
這個屬性是典型的模型表現與模型效率成反比的影響因子,即便如此,你還是應該儘可能提高這個數字,以讓你的模型更準確更穩定
2)criterion :度量分裂的標準。可選值:“mse”,均方差(mean squared error);“mae”,平均絕對值誤差(mean absolute error)
3)max_features :尋找最佳分裂點時考慮的屬性數目。可選值,int(具體的數目),float(數目的百分比),string(“auto”, “sqrt”,“log2”).
這一屬性是對單個樹來設定的,通常來講,這個值越大單棵樹可以考慮的屬性越多,則模型的表現就越好。但是這也不是肯定的,不過有一點是肯定的,增加這個值會導致演算法執行速度變慢,所以需要我們考慮去達到一個平衡。
4)max_depth : integer或者None。數的最大深度,如果None,節點擴充套件直到所有葉子是純的或者所有葉子節點包含的樣例數小於min_samples_split
5)min_samples_split : 分裂內部節點需要的最少樣例數。int(具體數目),float(數目的百分比)
6)min_samples_leaf :葉子節點上應有最少樣例數。int(具體數目),float(數目的百分比)。
更少的節點數使得模型更容易遭受noise data的影響,我通常設定這個值大於50,但是你需要尋找最適合你的數值。
7)max_leaf_nodes :以”最優優先方式”(best-first fashion),最優節點定義為:純度的相對減少.如果None則不限制葉子節點個數;[float]
8)min_impurity_split : 樹增長提前結束的閾值.對於當前節點,大於這個閾值將分裂,否則就看做葉子節點; [float]
9)min_impurity_decrease :一個閾值,表示一個節點分裂的條件是:如果這次分裂純度的減少大於等於這這個值.
10)bootstrap :構建數是不是採用有放回樣本的方式(bootstrap samples); [True/False]