データ入力として時系列を使用した分類タスクがあり、各属性(n = 23)は特定の時点を表します。絶対的な分類結果に加えて、どの属性/日付が結果にどの程度貢献しているのかを知りたいです。したがって、私はを使用feature_importances_
しています。
ただし、それらがどのように計算され、どのメジャー/アルゴリズムが使用されているかを知りたいです。残念ながら、このトピックに関するドキュメントは見つかりませんでした。
データ入力として時系列を使用した分類タスクがあり、各属性(n = 23)は特定の時点を表します。絶対的な分類結果に加えて、どの属性/日付が結果にどの程度貢献しているのかを知りたいです。したがって、私はを使用feature_importances_
しています。
ただし、それらがどのように計算され、どのメジャー/アルゴリズムが使用されているかを知りたいです。残念ながら、このトピックに関するドキュメントは見つかりませんでした。
回答:
実際、機能の「重要性」を取得するにはいくつかの方法があります。多くの場合、この単語の意味については厳密な合意はありません。
scikit-learnでは、[1]で説明されているように重要性を実装します(よく引用されますが、残念ながらめったに読まれません...)。これは「ジニ重要度」または「平均減少不純物」と呼ばれることもあり、すべてのノードで平均されたノード不純物の合計減少(そのノードに達する確率(そのノードに達するサンプルの割合で概算される)で重み付け)として定義されます。アンサンブルの木。
文献や他のいくつかのパッケージでは、「平均減少精度」として実装された機能の重要性を見つけることもできます。基本的には、その機能の値をランダムに並べ替えたときのOOBデータの精度の低下を測定するという考え方です。減少が少ない場合、機能は重要ではなく、その逆も同様です。
(両方のアルゴリズムがrandomForest Rパッケージで利用可能であることに注意してください。)
[1]:ブライマン、フリードマン、「分類と回帰木」、1984年。
tree_.compute_feature_importances(normalize=False)
ます。
単一ツリーの機能重要度値を計算する通常の方法は次のとおりです。
feature_importances
すべてゼロの配列をsizeで初期化しますn_features
。
ツリーをトラバースします。機能を分割する各内部ノードについてi
、そのノードのエラー削減にノードにルーティングされたサンプル数を掛けて計算し、この量をに追加しfeature_importances[i]
ます。
エラー削減は、使用する不純な基準(Gini、Entropy、MSEなど)によって異なります。内部ノードにルーティングされる一連の例の不純物から、分割によって作成された2つのパーティションの不純物の合計を差し引いたもの。
これらの値が特定のデータセット(エラー削減とサンプル数の両方がデータセット固有)に関連していることが重要なので、これらの値を異なるデータセット間で比較することはできません。
私の知る限り、決定木で機能の重要度の値を計算する別の方法があります。上記の方法の簡単な説明は、Trevor Hastie、Robert Tibshirani、Jerome Friedmanによる「統計学習の要素」にあります。
これは、学習セット内のサンプルの総数に対する、集団の任意のツリーでその機能を含む決定ノードにルーティングされたサンプルの数の間の比率です。
デシジョンツリーの最上位ノードに含まれる機能は、より多くのサンプルを参照する傾向があるため、より重要度が高くなる可能性があります。
編集:この説明は部分的にしか正しくありません。ジルとピーターの答えは正しい答えです。
@GillesLouppeが上記で指摘したように、scikit-learnは現在、機能の重要度に対して「平均不純化」メトリックを実装しています。私は個人的に、2つ目の指標をもう少し興味深いと思います。この場合、各機能の値を1つずつランダムに並べ替え、out-of-bagのパフォーマンスがどれほど悪いかを確認します。
機能の重要性は、各機能がモデル全体の予測パフォーマンスにどの程度貢献するかということなので、2番目の指標は実際にこれを直接測定するものですが、「平均減少不純物」は単なる適切なプロキシです。
興味があれば、置換重要度メトリックを実装し、scikit-learnランダムフォレストクラスのインスタンスから値を計算するために使用できる小さなパッケージを作成しました。
https://github.com/pjh2011/rf_perm_feat_import
編集:これは3ではなくPython 2.7で機能します
質問に答えてみましょう。コード:
iris = datasets.load_iris()
X = iris.data
y = iris.target
clf = DecisionTreeClassifier()
clf.fit(X, y)
Decision_tree plot:
ここに画像の説明を入力してください
compute_feature_importance:[0。、0.01333333,0.06405596,0.92261071]
ソースコードを確認:
cpdef compute_feature_importances(self, normalize=True):
"""Computes the importance of each feature (aka variable)."""
cdef Node* left
cdef Node* right
cdef Node* nodes = self.nodes
cdef Node* node = nodes
cdef Node* end_node = node + self.node_count
cdef double normalizer = 0.
cdef np.ndarray[np.float64_t, ndim=1] importances
importances = np.zeros((self.n_features,))
cdef DOUBLE_t* importance_data = <DOUBLE_t*>importances.data
with nogil:
while node != end_node:
if node.left_child != _TREE_LEAF:
# ... and node.right_child != _TREE_LEAF:
left = &nodes[node.left_child]
right = &nodes[node.right_child]
importance_data[node.feature] += (
node.weighted_n_node_samples * node.impurity -
left.weighted_n_node_samples * left.impurity -
right.weighted_n_node_samples * right.impurity)
node += 1
importances /= nodes[0].weighted_n_node_samples
if normalize:
normalizer = np.sum(importances)
if normalizer > 0.0:
# Avoid dividing by zero (e.g., when root is pure)
importances /= normalizer
return importances
機能の重要度を計算してみてください:
print("sepal length (cm)",0)
print("sepal width (cm)",(3*0.444-(0+0)))
print("petal length (cm)",(54* 0.168 - (48*0.041+6*0.444)) +(46*0.043 -(0+3*0.444)) + (3*0.444-(0+0)))
print("petal width (cm)",(150* 0.667 - (0+100*0.5)) +(100*0.5-(54*0.168+46*0.043))+(6*0.444 -(0+3*0.444)) + (48*0.041-(0+0)))
feature_importance:np.array([0,1.332,6.418,92.30])を取得します。
正規化した後、配列([0.、0.01331334、0.06414793、0.92253873])を取得できますclf.feature_importances_
。これはと同じです。
すべてのクラスが1つの重みを持つことになっていることに注意してください。
このトピックに関するscikit-learnのドキュメントへの参照、または@GillesLouppeによる回答への参照を探している人のために:
RandomForestClassifierでは、estimators_
attributeはDecisionTreeClassifierのリストです(ドキュメントで説明されています)。feature_importances_
RandomForestClassifierのを計算するために、scikit-learnのソースコードでfeature_importances_
は、アンサンブル内のすべての推定器(すべてのDecisionTreeClassifer)の属性を平均します。
DecisionTreeClassiferのドキュメントでは、「機能の重要性は、その機能によってもたらされる基準の(正規化された)総削減量として計算されます。Giniの重要性[1]とも呼ばれます。」
以下は、scikit-learnのリファレンスで提供されている、変数とGiniの重要性に関する詳細情報への直接リンクです。
[1] L.ブライマン、およびA.カトラー、「ランダムフォレスト」、http: //www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm