web-dev-qa-db-ja.com

scikit-learn分類子の最も有益な機能を取得する方法は?

Liblinearやnltkなどの機械学習パッケージの分類子は、show_most_informative_features()メソッドを提供します。これは、機能のデバッグに非常に役立ちます。

viagra = None          ok : spam     =      4.5 : 1.0
hello = True           ok : spam     =      4.5 : 1.0
hello = None           spam : ok     =      3.3 : 1.0
viagra = True          spam : ok     =      3.3 : 1.0
casino = True          spam : ok     =      2.0 : 1.0
casino = None          ok : spam     =      1.5 : 1.0

私の質問は、scikit-learnの分類器に同様のものが実装されているかどうかです。ドキュメントを検索しましたが、類似のものが見つかりませんでした。

そのような関数がまだない場合、誰かがそれらの値に到達するための回避策を知っていますか?

どうもありがとう!

63
tobigue

Larsmansコードの助けを借りて、バイナリケースのこのコードを思い付きました。

def show_most_informative_features(vectorizer, clf, n=20):
    feature_names = vectorizer.get_feature_names()
    coefs_with_fns = sorted(Zip(clf.coef_[0], feature_names))
    top = Zip(coefs_with_fns[:n], coefs_with_fns[:-(n + 1):-1])
    for (coef_1, fn_1), (coef_2, fn_2) in top:
        print "\t%.4f\t%-15s\t\t%.4f\t%-15s" % (coef_1, fn_1, coef_2, fn_2)
49
tobigue

分類子自体はフィーチャ名を記録せず、数値配列のみを表示します。ただし、Vectorizer/CountVectorizer/TfidfVectorizer/DictVectorizerを使用してフィーチャを抽出した場合、and線形モデル(たとえばLinearSVCまたはNaive Bayes)を使用している場合、 ドキュメント分類の例 が使用するのと同じトリックを適用できます。例(untested、バグが1つまたは2つ含まれている可能性があります):

def print_top10(vectorizer, clf, class_labels):
    """Prints features with the highest coefficient values, per class"""
    feature_names = vectorizer.get_feature_names()
    for i, class_label in enumerate(class_labels):
        top10 = np.argsort(clf.coef_[i])[-10:]
        print("%s: %s" % (class_label,
              " ".join(feature_names[j] for j in top10)))

これはマルチクラス分類用です。バイナリの場合、clf.coef_[0]のみを使用する必要があると思います。 class_labelsを並べ替える必要がある場合があります。

58
Fred Foo

更新を追加するために、RandomForestClassifier.feature_importances_属性。この attribute は、観測された分散のどれだけがその機能によって説明されるかを示します。明らかに、これらすべての値の合計は1以下でなければなりません。

フィーチャエンジニアリングを実行する場合、この属性は非常に便利です。

Scikit-learnチームとこれを実装してくれた貢献者に感謝します!

編集:これはRandomForestとGradientBoostingの両方で機能します。したがって、RandomForestClassifierRandomForestRegressorGradientBoostingClassifier、およびGradientBoostingRegressorはすべてこれをサポートしています。

15
ClimbsRocks

最近、ライブラリ( https://github.com/TeamHG-Memex/eli5 )をリリースしました。機能値に応じてテキストを強調表示する、IPythonと統合する、など.

9
Mikhail Korobov

NaiveBayes分類器で機能の重要性を実際に調べる必要があり、上記の関数を使用しましたが、クラスに基づいて機能の重要性を取得できませんでした。 scikit-learnのドキュメントを調べて、上記の機能を少し調整して、問題を解決できるようにしました。それがあなたにも役立つことを願っています!

def important_features(vectorizer,classifier,n=20):
    class_labels = classifier.classes_
    feature_names =vectorizer.get_feature_names()

    topn_class1 = sorted(Zip(classifier.feature_count_[0], feature_names),reverse=True)[:n]
    topn_class2 = sorted(Zip(classifier.feature_count_[1], feature_names),reverse=True)[:n]

    print("Important words in negative reviews")

    for coef, feat in topn_class1:
        print(class_labels[0], coef, feat)

    print("-----------------------------------------")
    print("Important words in positive reviews")

    for coef, feat in topn_class2:
        print(class_labels[1], coef, feat)

これが機能するには、分類子(私の場合はNaiveBayes)にfeature_count_属性が必要です。

2
Sai Sandeep

次のようなことを行って、重要度の特徴のグラフを順序別に作成することもできます。

importances = clf.feature_importances_
std = np.std([tree.feature_importances_ for tree in clf.estimators_],
         axis=0)
indices = np.argsort(importances)[::-1]

# Print the feature ranking
#print("Feature ranking:")


# Plot the feature importances of the forest
plt.figure()
plt.title("Feature importances")
plt.bar(range(train[features].shape[1]), importances[indices],
   color="r", yerr=std[indices], align="center")
plt.xticks(range(train[features].shape[1]), indices)
plt.xlim([-1, train[features].shape[1]])
plt.show()
1
Oleole

正確には探しているものではありませんが、最大のマグニチュード係数をすばやく取得する方法です(pandasデータフレーム列が機能名であると仮定):

次のようにモデルをトレーニングしました。

lr = LinearRegression()
X_train, X_test, y_train, y_test = train_test_split(df, Y, test_size=0.25)
lr.fit(X_train, y_train)

次のように、10個の最大の負の係数値を取得します(または最大の正の場合はreverse = Trueに変更します)。

sorted(list(Zip(feature_df.columns, lr.coef_)), key=lambda x: x[1], 
reverse=False)[:10]
0
slevin886

RandomForestClassifierにはまだcoef_属性がありませんが、0.17リリースではそうなると思います。ただし、 scikit-learnを使用したランダムフォレストでの再帰機能の削除RandomForestClassifierWithCoefクラスを参照してください。これにより、上記の制限を回避するためのアイデアが得られます。

0
Daisuke Aramaki