sklearnコードを使用しR
ます。これは一般にコードよりもずっときれいだからです。
GradientBoostingClassifierの feature_importancesプロパティの実装を次に示します(概念的なものを邪魔するコードの行をいくつか削除しました)
def feature_importances_(self):
total_sum = np.zeros((self.n_features, ), dtype=np.float64)
for stage in self.estimators_:
stage_sum = sum(tree.feature_importances_
for tree in stage) / len(stage)
total_sum += stage_sum
importances = total_sum / len(self.estimators_)
return importances
これは非常に理解しやすいです。 self.estimators_
は、ブースター内の個々のツリーを含む配列なので、forループは個々のツリーを反復処理します。との接続が1つあります
stage_sum = sum(tree.feature_importances_
for tree in stage) / len(stage)
これは、非バイナリ応答のケースを処理しています。ここでは、各段階で複数のツリーを1対すべての方法で適合させます。バイナリケースに焦点を当てるのが概念的に最も簡単なのは、合計に1つの被加数があり、これがちょうどである場合tree.feature_importances_
です。したがって、バイナリの場合、これをすべて次のように書き換えることができます。
def feature_importances_(self):
total_sum = np.zeros((self.n_features, ), dtype=np.float64)
for tree in self.estimators_:
total_sum += tree.feature_importances_
importances = total_sum / len(self.estimators_)
return importances
つまり、言葉で、個々のツリーの特徴の重要度を合計し、ツリーの総数で割ります。単一のツリーの機能の重要度を計算する方法はまだ残っています。
ツリーの重要度の計算は、cythonレベルで実装されますが、それでも引き続き追跡可能です。ここにコードのクリーンアップされたバージョンがあります
cpdef compute_feature_importances(self, normalize=True):
"""Computes the importance of each feature (aka variable)."""
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
return importances
これは非常に簡単です。ツリーのノードを反復処理します。リーフノードにいない限り、このノードでの分割からノード純度の重み付き減少を計算し、分割されたフィーチャに帰属させます
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)
次に、完了したら、データの総重み(ほとんどの場合、観測値の数)ですべてを分割します。
importances /= nodes[0].weighted_n_node_samples
不純物は、ツリーを成長させるときに分割するものを決定するときに使用するメトリックの一般的な名前であることを思い出してください。その観点から、各フィーチャでの分割がどれだけツリー内のすべての分割で不純物を削減できるかを単純に要約しています。
勾配ブースティングのコンテキストでは、これらのツリーは常に損失ツリーの勾配に適合する回帰ツリー(貪欲に二乗誤差を最小化)です。