ランダムフォレストを使用して機能の重要性を評価する

序文

ランダムフォレストは、意思決定ツリーの学習者に基づく統合学習アルゴリズムです。ランダムフォレストは、非常にシンプルで実装が簡単で、計算のオーバーヘッドが少ないです。さらに驚くべきことは、分類と回帰で驚くべきパフォーマンスを示していることです。したがって、ランダムフォレストは、「統合学習テクノロジーのレベルを表す方法」としても知られています。 "。 
この記事は、機能の選択でランダムフォレストがどのように使用されるかについての簡単な紹介です。

ランダムフォレスト(RF)の概要

決定ツリーのアルゴリズムを理解している限り、ランダムフォレストはかなり理解しやすいです。ランダムフォレストアルゴリズムは、次の手順で要約できます。

  1. サンプリング置換(ブートストラップ)の方法を使用して、サンプルセットからn個のサンプルをトレーニングセットとして選択します
  2. サンプリングによって取得したサンプルセットを使用して、決定ツリーを生成します。生成された各ノードで: 
    • 繰り返しなしでランダムにd個の機能を選択
    • これらのd特徴を使用してサンプルセットを分割し、最適な分割特徴を見つけます(Gini係数、ゲインレート、または情報ゲインで判断できます)
  3. 手順1から手順2を合計k回繰り返します。kはランダムフォレスト内の決定ツリーの数です。
  4. トレーニングされたランダムフォレストを使用してテストサンプルを予測し、投票方法を使用して予測結果を決定します。

次の図は、ランダムフォレストアルゴリズムをより直感的に示しています(図は文献2からのものです)。 

ランダムフォレストアルゴリズム

 

図1:ランダムフォレストアルゴリズムの概略図


そうです、これはどこでもランダムに選択されるアルゴリズムです。分類と回帰で優れた結果が得られます。説明するには強すぎると思いますか? 
ただし、この記事の焦点はこれではなく、次の機能の重要性の評価です。 。

 

機能の重要性の評価

実際には、データセットには何百もの以前の機能が含まれていることがよくあります。モデルを構築するときに機能の数を減らすために、結果に最も大きな影響を与える機能を選択する方法は、私たちがより懸念している問題です。実際には、主成分分析やなげなわなど、そのような方法はたくさんあります。ただし、ここで紹介するのは、ランダムフォレストを使用してフィーチャをフィルタリングすることです。 
ランダムフォレストを使用して機能の重要性を評価するというアイデアは、実際には非常に単純です。率直に言って、各機能がランダムフォレスト内の各ツリーにどの程度貢献しているかを確認し、平均値を取得して、最後に機能を比較することです。貢献のサイズ。 
さて、この貢献は何ですか?通常、Giniインデックス(Giniインデックス)またはout-of-bagデータ(OOB)エラー率で測定できます。 
Giniインデックスを使用して評価する方法のみを紹介します。別の方法を知りたい場合は、文献2を参照してください。 
mmフィーチャX1、X2、X3、...、XcX1、X2、X3、...、Xcがあると仮定して、VIMVIMを使用して可変重要度を表し、GIGIを使用してGiniインデックスを表します。次に、各フィーチャXjXjのGiniインデックススコアVIM(Gini)jVIMj(Gini)、つまり、RFのすべての決定ツリーにおけるjj番目のフィーチャのノード分割不純物の平均変化を計算する必要があります。 
ジニ指数の計算式は次のとおりです。 

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から2つのサンプルがランダムに選択され、それらのカテゴリラベルに一貫性がない可能性があります。 
ノードmmでの機能XjXjの重要性、つまりノードmmの分岐前後のGiniGiniインデックスの変更は次のとおりです。 

VIM(Gini)jm = GIm − GIl − GIrVIMjm(Gini)= GIm − GIl − GIr


その中で、GIlGIlとGIrGIrはそれぞれ、分岐後の2つの新しいノードのGiniGiniインデックスを表します。 
決定ツリーiiの機能XjXjのノードがセットMMにある場合、i番目のツリーでのXjXjの重要性は次のようになります。 

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

 

例えば

幸い、sklearnはすでにすべてをカプセル化しており、その中の関数を呼び出すだけで済みます。 
例としてUCIのワインの例を見てみましょう。最初にデータセットをインポートします。

import pandas as pd
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data'
df = pd.read_csv(url, header = None)
df.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']

次に、現時点でどのようなデータセットであるかを大まかに見てみましょう。

import numpy as np
np.unique(df['Class label'])

出力は

array([1, 2, 3], dtype=int64)

3つのカテゴリーがあることがわかります。次に、データ情報を確認します。

df.info()

出力は

<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

クラスラベルを除いて13の機能があり、データセットのサイズは178であることがわかります。 
従来の慣例によれば、データセットはトレーニングセットとテストセットに分けられます。

from sklearn.cross_validation import train_test_split
from sklearn.ensemble import RandomForestClassifier
x, y = df.iloc[:, 1:].values, df.iloc[:, 0].values
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 0)
feat_labels = df.columns[1:]
forest = RandomForestClassifier(n_estimators=10000, random_state=0, n_jobs=-1)
forest.fit(x_train, y_train)

さて、このようにして、ランダムな森が訓練され、特徴の重要性が評価されました。見てみましょう。

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) Color intensity                0.182483
 2) Proline                        0.158610
 3) Flavanoids                     0.150948
 4) OD280/OD315 of diluted wines   0.131987
 5) Alcohol                        0.106589
 6) Hue                            0.078243
 7) Total phenols                  0.060718
 8) Alcalinity of ash              0.032033
 9) Malic acid                     0.025400
10) Proanthocyanins                0.022351
11) Magnesium                      0.022078
12) Nonflavanoid phenols           0.014645
13) Ash                            0.013916

はい、とても便利です。 
より重要な変数を除外したい場合は、これを行うことができます

threshold = 0.15
x_selected = x_train[:, importances > threshold]
x_selected.shape

出力は

(124, 3)

いいえ、重要度が0.15を超える3つの機能を選択しましたか?

参照

[1] Raschka S. Python Machine Learning [M]。PacktPublishing、2015年。
[2] Yang Kai、Hou Yan、LiKang  。ランダムな森林変数の重要度スコアとその研究の進歩[J]。2015年。

 

転載元:https//blog.csdn.net/zjuPeco/article/details/77371645?locationNum = 7&fps = 1

おすすめ

転載: blog.csdn.net/xiezhen_zheng/article/details/82011908