利用随机森林对特征重要性进行评估 方法一
https://hal.archives-ouvertes.fr/file/index/docid/755489/filename/PRLv4.pdf
前言
隨機森林是以決策樹為基學習器的集成學習算法。隨機森林非常簡單,易于實現,計算開銷也很小,更令人驚奇的是它在分類和回歸上表現出了十分驚人的性能,因此,隨機森林也被譽為“代表集成學習技術水平的方法”。?
本文是對隨機森林如何用在特征選擇上做一個簡單的介紹。
隨機森林(RF)簡介
只要了解決策樹的算法,那么隨機森林是相當容易理解的。隨機森林的算法可以用如下幾個步驟概括:
- 隨機不重復地選擇d個特征
- 利用這d個特征分別對樣本集進行劃分,找到最佳的劃分特征(可用基尼系數、增益率或者信息增益判別)
下圖比較直觀地展示了隨機森林算法(圖片出自文獻2):?
?
圖1:隨機森林算法示意圖
沒錯,就是這個到處都是隨機取值的算法,在分類和回歸上有著極佳的效果,是不是覺得強的沒法解釋~?
然而本文的重點不是這個,而是接下來的特征重要性評估。
?
特征重要性評估
現實情況下,一個數據集中往往有成百上前個特征,如何在其中選擇比結果影響最大的那幾個特征,以此來縮減建立模型時的特征數是我們比較關心的問題。這樣的方法其實很多,比如主成分分析,lasso等等。不過,這里我們要介紹的是用隨機森林來對進行特征篩選。?
用隨機森林進行特征重要性評估的思想其實很簡單,說白了就是看看每個特征在隨機森林中的每顆樹上做了多大的貢獻,然后取個平均值,最后比一比特征之間的貢獻大小。?
好了,那么這個貢獻是怎么一個說法呢?通常可以用基尼指數(Gini index)或者袋外數據(OOB)錯誤率作為評價指標來衡量。?
我們這里只介紹用基尼指數來評價的方法,想了解另一種方法的可以參考文獻2。?
我們將變量重要性評分(variable importance measures)用VIMVIM來表示,將Gini指數用GIGI來表示,假設有mm個特征X1,X2,X3,...,XcX1,X2,X3,...,Xc,現在要計算出每個特征XjXj的Gini指數評分VIM(Gini)jVIMj(Gini),亦即第jj個特征在RF所有決策樹中節點分裂不純度的平均改變量。?
Gini指數的計算公式為?
GIm=∑|K|k=1∑k′≠kpmkpmk′=1?∑|K|k=1p2mkGIm=∑k=1|K|∑k′≠kpmkpmk′=1?∑k=1|K|pmk2
其中,KK表示有KK個類別,pmkpmk表示節點mm中類別kk所占的比例。?
直觀地說,就是隨便從節點mm中隨機抽取兩個樣本,其類別標記不一致的概率。?
特征XjXj在節點mm的重要性,即節點mm分枝前后的GiniGini指數變化量為?
VIM(Gini)jm=GIm?GIl?GIrVIMjm(Gini)=GIm?GIl?GIr
其中,GIlGIl和GIrGIr分別表示分枝后兩個新節點的GiniGini指數。?
如果,特征XjXj在決策樹ii中出現的節點在集合MM中,那么XjXj在第ii顆樹的重要性為?
VIM(Gini)ij=∑m∈MVIM(Gini)jmVIMij(Gini)=∑m∈MVIMjm(Gini)
假設RFRF中共有nn顆樹,那么?
VIM(Gini)j=∑ni=1VIM(Gini)ijVIMj(Gini)=∑i=1nVIMij(Gini)
最后,把所有求得的重要性評分做一個歸一化處理即可。?
VIMj=VIMj∑ci=1VIMiVIMj=VIMj∑i=1cVIMi
?
舉個例子
值得慶幸的是,sklearnsklearn已經幫我們封裝好了一切,我們只需要調用其中的函數即可。?
我們以UCI上葡萄酒的例子為例,首先導入數據集。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
然后,我們來大致看下這時一個怎么樣的數據集
import numpy as np np.unique(df['Class label'])- 1
- 2
輸出為
array([1, 2, 3], dtype=int64)- 1
可見共有3個類別。然后再來看下數據的信息:
df.info()- 1
輸出為
<class 'pandas.core.frame.DataFrame'> RangeIndex: 178 entries, 0 to 177 Data columns (total 14 columns): Class label 178 non-null int64 Alcohol 178 non-null float64 Malic acid 178 non-null float64 Ash 178 non-null float64 Alcalinity of ash 178 non-null float64 Magnesium 178 non-null int64 Total phenols 178 non-null float64 Flavanoids 178 non-null float64 Nonflavanoid phenols 178 non-null float64 Proanthocyanins 178 non-null float64 Color intensity 178 non-null float64 Hue 178 non-null float64 OD280/OD315 of diluted wines 178 non-null float64 Proline 178 non-null int64 dtypes: float64(11), int64(3) memory usage: 19.5 KB- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
可見除去class label之外共有13個特征,數據集的大小為178。?
按照常規做法,將數據集分為訓練集和測試集。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
好了,這樣一來隨機森林就訓練好了,其中已經把特征的重要性評估也做好了,我們拿出來看下。
importances = forest.feature_importances_ indices = np.argsort(importances)[::-1] for f in range(x_train.shape[1]):print("%2d) %-*s %f" % (f + 1, 30, feat_labels[indices[f]], importances[indices[f]]))- 1
- 2
- 3
- 4
輸出的結果為
1) Color intensity 0.1824832) Proline 0.1586103) Flavanoids 0.1509484) OD280/OD315 of diluted wines 0.1319875) Alcohol 0.1065896) Hue 0.0782437) Total phenols 0.0607188) Alcalinity of ash 0.0320339) Malic acid 0.025400 10) Proanthocyanins 0.022351 11) Magnesium 0.022078 12) Nonflavanoid phenols 0.014645 13) Ash 0.013916- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
對的就是這么方便。?
如果要篩選出重要性比較高的變量的話,這么做就可以
- 1
- 2
- 3
輸出為
(124, 3)- 1
瞧,這不,幫我們選好了3個重要性大于0.15的特征了嗎~
參考文獻
[1] Raschka S. Python Machine Learning[M]. Packt Publishing, 2015.?
[2] 楊凱, 侯艷, 李康. 隨機森林變量重要性評分及其研究進展[J]. 2015.
?
總結
以上是生活随笔為你收集整理的利用随机森林对特征重要性进行评估 方法一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抓住时机
- 下一篇: OPPO 后端开发 一、二、HR 面面经