特徵重要性評估的隨機森林演算法與Python實現(三)

郝hai發表於2024-05-02

特徵重要性評估(Variable importance measure, or Feature importance evaluation,VIM)用來計算樣本特徵的重要性,定量地描述特徵對分類或者回歸的貢獻程度。隨機森林(Random Forest)作為一種強大的機器學習演算法,在特徵重要性評估方面具有顯著優勢。特徵重要新評估是隨機森林的一種自帶工具,主要分為兩種方法:一種是平均不純度的減少(mean decrease impurity),常用gini /entropy /information gain測量,現在sklearn中用的就是這種方法;另一種是平均準確率的減少(mean decrease accuracy),常用袋外誤差率去衡量。這兩種方法的思想都是Leo Breiman提出的,特徵重要性評估可以幫助我們理解模型是如何做出預測的,哪些特徵對於模型的決策至關重要。

一、特徵重要性評估步驟

構建隨機森林模型: 首先,需要使用隨機森林演算法構建一個模型。隨機森林由多個決策樹組成,每個決策樹都是基於對原始資料的不同隨機子樣本和特徵子集的訓練而得到的。
評估每個特徵的重要性: 隨機森林透過對每個特徵在樹的構建過程中所造成的不純度減少來評估其重要性。特徵重要性可以透過兩種方式進行計算:a. Mean Decrease Impurity(MDI): 這種方法透過計算每個特徵在每棵決策樹中節點劃分時的不純度減少量的平均值來評估特徵的重要性。通常情況下,不純度的衡量指標是基尼不純度或熵。b. Mean Decrease Accuracy(MDA): 這種方法透過在每個決策樹中計算特徵對模型準確率的影響來評估特徵的重要性。
特徵重要性的歸一化: 在某些情況下,特徵重要性的值需要進行歸一化,以便比較不同特徵之間的相對重要性。
視覺化或排序: 最後,可以將特徵重要性的結果視覺化,或者按照重要性進行排序,以便更好地理解哪些特徵對模型的預測起著關鍵作用。

二、特徵重要性評估的應用

特徵重要性評估在各個領域的資料科學和機器學習應用中都有廣泛的應用:

金融領域: 在金融領域,特徵重要性評估可以幫助銀行和金融機構識別最重要的客戶特徵,用於信用評分、風險管理和欺詐檢測等任務。
醫療保健: 在醫療保健領域,特徵重要性評估可以用於分析醫療資料,識別對於疾病診斷和預測最為關鍵的特徵,輔助醫生進行診斷和治療決策。
市場營銷: 在市場營銷領域,特徵重要性評估可以幫助企業瞭解哪些因素對於產品銷售和市場推廣最為重要,從而最佳化營銷策略和資源分配。
環境科學: 在環境科學領域,特徵重要性評估可以用於分析環境資料,識別對於氣候變化、環境汙染等問題最為關鍵的特徵,為環境保護和可持續發展提供支援。

透過調整隨機森林中的引數,如決策樹的數量、決策樹的最大深度、隨機選擇特徵的數量等,可以進一步最佳化特徵重要性的評估結果。此外,隨機森林還可以用於特徵選擇,透過選擇重要性較高的特徵來建立更加精確的模型。

三、 隨機森林常規的變數重要性評分

在隨機森林中,特徵的重要性可以透過多種方式進行評估,包括基尼指數(Gini index)和袋外資料(Out-of-Bag,OOB)錯誤率等。其中,基尼指數是一種衡量特徵對分類結果影響的指標,而袋外資料錯誤率則是透過計算每個特徵在隨機森林中的每棵樹的OOB錯誤率來評估特徵的重要性。現假定有變數 \(( X_1, X_2, \ldots, X_M )\),需要計算出 $ M $ 個變數重要性統計量(VIM),變數 $ X_j$的得分統計量分別用 $ VIM_j^{(Gini)} $ 和 $ VIM_j^{(OOB)} $ 表示。

3.1 Gini指數

統計量 $ VIM_j^{(Gini)}$表示第 \(j\)個變數在隨機森林所有樹中節點分裂不純度的平均改變數。Gini指數的計算公式為:

\[GI_m = \sum_{k=1}^K \hat{p}_{mk}(1 - \hat{p}_{mk}) \quad (1) \]

其中,$ K$ 為自助樣本集的類別數,$ \hat{p}_{mk} $ 為節點 \(m\)樣本屬於第\(k\) 類的機率估計值。當樣本為二分類資料時(\(K = 2\)),節點\(m\) 的 Gini指數為:

\[GI_m = 2 \hat{p}_m(1 - \hat{p}_m) \quad (2) \]

$ \hat{p}_m $ 為樣本在節點 $ m $ 屬於任意一類的機率估計值。
變數 $ X_j $ 在節點 $ m $ 的重要性,即節點$ m $ 分枝前後 Gini指數變化量為:

\[VIM_{jm}^{(Gini)} = GI_m - GI_l - GI_r \quad (3) \]

其中,$ GI_l $ 和 $ GI_r $ 分別表示由節點$ m $ 分裂的兩新節點的 Gini 指數。
如果變數 $X_j $ 在第 $ i $ 棵樹中出現 $ M$ 次,則變數 $ X_j$ 在第 $ i $ 棵樹的重要性為:

\[VIM_{ij}^{(Gini)} = \sum_{m=1}^M VIM_{jm}^{(Gini)} \quad (4) \]

變數 $ X_j $ 在隨機森林中的 Gini 重要性定義為:

\[VIM_j^{(Gini)} = \frac{1}{n} \sum_{i=1}^n VIM_{ij}^{(Gini)} \quad (5) \]

其中\(n\) 為隨機森林中分類樹的數量。

3.2 OOB錯誤率

$VIM_j^{(OOB)} $ 的定義為:在隨機森林的每棵樹中,使用隨機抽取的訓練自助樣本建樹,並計算袋外資料(OOB)的預測錯誤率,然後隨機置換變數$ X_j $ 的觀測值後再次建樹並計算 OOB 的預測錯誤率,最後計算兩次 OOB 錯誤率的差值經過標準化處理後在所有樹中的平均值即為變數 $ X_j$ 的置換重要性\((VIM_j^{(OOB)})\)
變數 \(X_j\) 在第 \(i\) 棵樹的 $ VIM_j^{(OOB)}$為:

\[VIM_j^{(OOB)} = \frac{\sum_{p=1}^{n_o^i}I(Y_p=Y_p^i)}{n_o^i} - \frac{\sum_{p=1}^{n_o^i}I(Y_p=Y_{p,\pi_j}^i)}{n_o^i} \]

其中,$ n_o^i $ 為第 $ i $ 棵樹 OOB 資料的觀測例數,$ I(g) $ 為指示函式,即兩值相等時取 1,不等時取 0;\(( Y_p \in \{0, 1\} )\) 為第 ( p ) 個觀測的真實結果,\(( Y_p^i \in \{0, 1\})\) 為隨機置換前第 $ i $ 棵樹對 OOB 資料第 \(p\)個觀測的預測結果,\(( Y_{p,\pi_j}^i \in \{0, 1\})\)為隨機置換後第 $ i $ 棵樹對 OOB 資料第 $ p $ 個觀測的預測結果。
當變數$ j $ 沒有在第 \(i\) 棵樹中出現時,$ VIM_{ij}^{(OOB)} = 0$。
變數 $ X_j$ 在隨機森林中的置換重要性定義為:

\[VIM_j^{(OOB)} = \frac{\sum_{i=1}^n VIM_{ij}^{(OOB)}}{n} \]

其中\(n\) 為隨機森林中分類樹的數量。

3.3 分類與迴歸的MDA方法

MDA方法透過隨機交換樣本的特徵資料,來衡量特徵對模型預測準確度的影響。以下是MDA計算的公式,分別對應分類\(MDAc(j)\)和迴歸\(MDAr(j)\)情形。

  • 分類:

\[MDA_c(j) = \frac {1}{T} \sum_{t=1}^{T} \left[ \frac{1}{|D_t|} \left( \sum_{X_i \in D_t} I(P(X_i)==y_i) - \sum_{X_i^j \in D_t^j} I(P(X_i^j)==y_i) \right) \right] \]

  • 迴歸:

\[MDA_r(j) = \frac {1}{T} \sum_{t=1}^{T} \left[ \frac{1}{|D_t|} \left( \sum_{X_i^j \in D_t^j} \sum_k (R_k(X_i^j) - y_i^k)^2 - \sum_{X_i \in D_t} \sum_k (R_k(X_i) - y_i^k)^2 \right) \right] \]

其中,\(T\): RF中隨機樹的數量;\((x_i, y_i)\): 樣本,對於分類,\(y_i\)為類別,對於迴歸為輸出(可以是多維);\(X_i^j\): \(X_i\)的第 \(j\) 維(特徵)隨機交換後的樣本;\(D_t\): 隨機樹\(t\) 的袋外(OOB)樣本集,\(D_t^j\): 第\(j\) 維交換後形成的樣本集;\(P(X_i)\): 樣本 \(X_i\) 的預測結果(類別);\(R(X_i)\):樣本 \(X_i\) 的預測輸出(迴歸);\(I(P({X_i})=y_i\) ): 指示函式,如果預測結果與真實類別相同,則返回1,否則返回0;\(y_i^k\): 考慮到多目標迴歸,表示第\(k\)維輸出。
MDA公式反映了對樣本第 \(j\) 維特徵上的資料進行隨機交換後,模型預測(分類)準確度或者(迴歸)精度下降的程度,使用的是每棵樹的袋外資料。如果在隨機交換後,準確度下降較多,則認為這個特徵比較重要。
上面公式中 \(MDA_c(j)\)\(MDA_r(j)\) 被稱為raw score。對於$MDA_c(j) ,在數值上它反映的是當特徵 \(J\) 被隨機交換後,袋外樣本的平均分類正確率的下降值;對於 \(MDA_r(j)\),在數值上它反映的是當特徵 \(j\) 被隨機交換後,袋外樣本均方誤差(MSE)的上升數值。

四、特徵重要性的Python程式碼

4.1 特徵比較示例1

一個資料集中往往有成百上千個特徵,如何在其中選擇比結果影響最大的那幾個特徵,以此來縮減建立模型時特徵數是我們比較關心的問題。這樣的方法其實很多,比如主成分分析,lasso等等。用隨機森林方法也可以進行特徵篩選。隨機森林進行特徵重要性評估的思想就是看每個特徵在隨機森林中的每棵樹上做了多大的貢獻,然後取個平均值,最後比一位元徵之間的貢獻大小。

# url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data'
# 從這個網址下載資料編輯成資料檔案wine.txt,放到工作路徑中

import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

# 讀取資料集
url1 = pd.read_csv(r'wine.txt', header=None)
url1.columns = ['Class label', 'Alcohol', 'Malic acid', 'Ash',
                'Alcalinity of ash', 'Magnesium', 'Total phenols',
                'Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins',
                'Color intensity', 'Hue', 'OD280/OD315 of diluted wines', 'Proline']

# 將資料集分為特徵和標籤
x, y = url1.iloc[:, 1:].values, url1.iloc[:, 0].values
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=0)

# 構建隨機森林模型
forest = RandomForestClassifier(n_estimators=10000, random_state=0, n_jobs=-1)
forest.fit(x_train, y_train)

# 獲取特徵重要性
importances = forest.feature_importances_
feat_labels = url1.columns[1:]
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]]))

# 設定重要性閾值,篩選變數
threshold = 0.15
x_selected = x_train[:, importances > threshold]

# 視覺化特徵重要性
plt.figure(figsize=(10, 6))
plt.title("紅酒資料集中各個特徵的重要程度", fontsize=18)
plt.ylabel("Importance level", fontsize=15, rotation=90)
plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False

for i in range(x_train.shape[1]):
    plt.bar(i, importances[indices[i]], color='orange', align='center')

plt.xticks(np.arange(x_train.shape[1]), feat_labels[indices], rotation=90, fontsize=15)
plt.show()

4.2 特徵重要性示例2

使用waveform資料集,訓練樣本數5000,特徵40維,類別數3。RF引數為隨機樹200棵,分類候選特徵數 \(\sqrt{40}\) ,執行5次得到以下特徵重要性的柱狀圖,顯示每個特徵重要性的平均值及標準差。這個資料是經典的用於特徵重要性評估驗證的資料集,它的後19維特徵是隨機噪聲,計算結果符合上述情況。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_openml
from sklearn.ensemble import RandomForestClassifier

# 載入Waveform資料集
waveform_data = fetch_openml(name='waveform-5000')
X, y = waveform_data.data, waveform_data.target

# 訓練隨機森林模型
clf = RandomForestClassifier(n_estimators=200, max_features='sqrt', random_state=42)
clf.fit(X, y)

# 提取特徵重要性
feature_importances = clf.feature_importances_

# 特徵重要性排序
sorted_indices = np.argsort(feature_importances)[::-1]
sorted_features = np.array(waveform_data.feature_names)[sorted_indices]
sorted_importances = feature_importances[sorted_indices]

# 繪製前15個特徵重要性排序圖
plt.figure(figsize=(10, 6))
plt.bar(range(15), sorted_importances[:15], tick_label=sorted_features[:15])
plt.title('Top 15 Feature Importance Ranking')
plt.xlabel('Feature')
plt.ylabel('Importance')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

4.3 特徵重要性迴歸示例

使用Tetuan-City-power-consumption資料集來進行試驗,原始資料集是透過時間、溫度、溼度、風速等6個變數來預測城市3個配電網的能源消耗,即輸入6維,輸出3維。由於“時間”變數難以使用,所以分解為[minute,hour,day,month,weekday,weekofyear] 6個變數,加上原始的5個氣象變數 (temperature, light, sound, CO2 and digital passive infrared (PIR)),形成新的11維輸入。隨機迴歸森林的引數為:隨機樹\(T=200\),分類候選特徵數 \(\frac{11}{3}\),節點最小樣本數5,最大樹深度40,都是預設引數。可以看到hour,month,weekofyear,氣溫這四個特徵(變數)的重要性排名前列,符合常理。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split

# 本地資料集路徑
file_path = "TetuanCity.csv"

# 讀取資料
data = pd.read_csv(file_path)

# 提取時間特徵
data['DateTime'] = pd.to_datetime(data['DateTime'])
data['minute'] = data['DateTime'].dt.minute
data['hour'] = data['DateTime'].dt.hour
data['day'] = data['DateTime'].dt.day
data['month'] = data['DateTime'].dt.month
data['weekday'] = data['DateTime'].dt.weekday
data['weekofyear'] = data['DateTime'].dt.isocalendar().week

# 選取特徵
features = ['minute', 'hour', 'day', 'month', 'weekday', 'weekofyear',
            'Temperature', 'Humidity', 'Wind Speed', 'general diffuse flows', 'diffuse flows']

X = data[features]
y = data[['Zone 1 Power Consumption', 'Zone 2  Power Consumption', 'Zone 3  Power Consumption']]

# 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 訓練隨機迴歸森林模型
rf = RandomForestRegressor(n_estimators=200, max_features='auto', min_samples_leaf=5, max_depth=40, random_state=42)
rf.fit(X_train, y_train)

# 提取特徵重要性
feature_importances = rf.feature_importances_

# 特徵重要性排序
sorted_indices = np.argsort(feature_importances)[::-1]
sorted_features = np.array(features)[sorted_indices]
sorted_importances = feature_importances[sorted_indices]

# 繪製特徵重要性排序圖
plt.figure(figsize=(10, 6))
plt.bar(range(len(features)), sorted_importances, tick_label=sorted_features)
plt.title('Feature Importance Ranking')
plt.xlabel('Feature')
plt.ylabel('Importance')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

總結

特徵重要性評估是在隨機森林等機器學習演算法中廣泛使用的技術。其核心思想是透過量化每個特徵對模型預測的貢獻度,幫助理解模型的工作原理、進行特徵選擇和解釋模型的決策過程。透過特徵重要性評估,可以確定資料集中最具預測性的特徵,最佳化模型的效能,增強模型的解釋性和可理解性。評估方法包括基於不純度減少和準確率下降的計算,可以透過排序和視覺化展示特徵的重要性。特徵重要性評估在金融、醫療、市場營銷等領域都有廣泛的應用,是資料科學和機器學習中的重要工具之一。特徵重要性評估是隨機森林演算法中的一個重要應用。在隨機森林中,特徵的重要性可以透過計算每個特徵在隨機森林中的每棵樹上所做的貢獻來評估,然後取平均值,最後比較特徵之間的貢獻大小。這種評估方法有助於在資料集中選擇對結果影響最大的特徵,從而縮減建立模型時所需的特徵數量,隨機森林演算法在特徵重要性評估方面具有很大的優勢,能夠有效地幫助人們從資料集中選擇出對結果影響最大的特徵,從而提高模型的精度和效能。

參考資料

  1. 隨機森林特徵重要性(Variable importance)評估方法
  2. 利用隨機森林對特徵重要性進行評估(公式原理)
  3. 特徵重要度整理 - 隨機森林、邏輯迴歸

相關文章