matatabipower
@matatabipower

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

feature importanceはすべての説明変数について算出できないのでしょうか?

解決したいこと

基本的な質問で申し訳ないのですが、
説明変数は30個くらいあるのに、feature importanceで表示されるのは一部の変数だけでした。
関連が深い項目しか表示されないのでしょうか?
以下はコードですが、これはシグネイトの林型分類のために書いたコードで、
これを改変して実際に解析したいデータに当てはめてみました。

import xgboost as xgb
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, classification_report

forest = pd.read_csv("./python/train2.csv")

import seaborn as sns
forest_corr = forest.corr()
print(forest_corr)
sns.heatmap(forest_corr,vmax=1, vmin=-1, center=0)
import matplotlib.pyplot as plt
plt.show()

#訓練データとテストデータの取得
from sklearn.model_selection import train_test_split

#ここではA.B.C...で省略していますが、説明変数が30個あります。
forest_data = pd.DataFrame(forest, columns=["A", "B", "C", "D","E", "F", "G",
"H"])
print(forest_data)
forest_target=pd.Series(forest["Cover_Type"])
print(forest_target)

#訓練データとテストデータの取得(テストが0.2,訓練が0.8)
from sklearn.model_selection import train_test_split

train_x, test_x, train_y, test_y = train_test_split(forest_data, 
                                                    forest_target, 
                                                    test_size=0.2, 
                                                    shuffle=True)

#xgboost用の型に変換する
dtrain = xgb.DMatrix(train_x, label=train_y)

#パラメータの設定 max_depth:木の最大深度 eta:学習率 objective:学習目的 num_class:クラス数
param = {'max_depth': 2, 'eta': 1, 'objective': 'multi:softmax', 'num_class':3}

#学習
num_round = 10
bst = xgb.train(param, dtrain, num_round)

#予測
dtest = xgb.DMatrix(test_x)
pred = bst.predict(dtest)


#精度の確認
from sklearn.metrics import accuracy_score
from sklearn.metrics import r2_score

score = accuracy_score(test_y, pred)
print('score:{0:.4f}'.format(score))

#重要度の可視化
xgb.plot_importance(bst)
plt.show()

print(pred.shape)
print(pred)

print(test_y, pred)

print(r2_score(test_y,pred))

自分で試したこと

feature importanceに表示される項目が1個だったり3個だったりします。

すべての項目について貢献度を知りたいと思うのですが、
表示されていないものは全く貢献していないということなのでしょうか?

原因としてデータが30セットしかないことも影響していると思いますが、
よくわかりません。
アドバイスを頂けると助かります。
よろしくお願いいたします。

0

1Answer

基本的にコーディング関係の質問の場合にはコードを貼り付けましょう。
「```python(改行してその下にコードを書く)```」でマークダウン形式でコードを記述することができます。

0Like

Comments

  1. @matatabipower

    Questioner

    アドバイスをありがとうございます!
    コードを貼ってみました。
    よろしくお願いいたします。

  2. コードの貼付ありがとうございます。
    あとは依存ファイルがあるためコピペするだけでは動かないので、出力結果も記載することが望ましいです。

    それはさておき、FeatureImportanceがすべて出力されないということですが、公式ドキュメントを参照してみた所、max_num_featuresという引数で設定できるようです。
    「Maximum number of top features displayed on plot. If None, all features will be displayed.」と記載されているためデフォルトはすべての特徴量を出力するはずです。

    公式ドキュメント:https://xgboost.readthedocs.io/en/stable/python/python_api.html#module-xgboost.plotting

    以下のコードはStackOverflowから引っ張ってきたものです。
    インスタンス生成またはboosterの取得でのエラーの場合には以下のコードコピペで解決するかもしれません。

    feature_importance = bst.get_booster().get_score(importance_type='weight')
    keys = list(feature_important.keys())
    values = list(feature_important.values())
    
    data = pd.DataFrame(data=values, index=keys, columns=["score"]).sort_values(by = "score", ascending=False)
    data.nlargest(40, columns="score").plot(kind='barh', figsize = (20,10))
    

    余談ですがFeatureImportanceには3種類あっておそらくGainImportanceが最も参考になると思います。(次いでCoverImportanceかなと)
    今デフォルトのImportanceでWeightImportanceになっていると思いますのでもしかするとその部分も調べたほうが良いかもしれません。

  3. @matatabipower

    Questioner

    詳しくありがとうございます!!
    試しに特徴量が32あるので

    xgb.plot_importance(bst,
                        importance_type='gain',
                        max_num_features=32,
                        show_values=True)
    plt.show()
    

    と記載してみましたがやはりすべては表示されません。
    しかしimportanceをgainにしてみたところ、weightの時2つか3つしか表示されなかった特徴量が4つから5つに増えました。
    出力はこうでした
    Figure_2.png

    また、お教えいただいたコードもコピペしてみました。

    feature_importance = bst.get_booster().get_score(importance_type='weight')
    keys = list(feature_importance.keys())
    values = list(feature_importance.values())
    
    data = pd.DataFrame(data=values, index=keys, columns=["score"]).sort_values(by = "score", ascending=False)
    data.nlargest(40, columns="score").plot(kind='barh')
    
    plt.show()
    

    get_booster().の部分でAttributeError: 'Booster' object has no attribute 'get_booster'
    がでるので、その部分を削除したところ、4つだけscoreが表示されました。
    Figure_4.png

    コピペしたコードをweightからgainに替えたところ、
    上のコードとコピペしたコードで出力される図は全く同じになりました。

    もともと林型の分類で使ったコードなのでそれの出力もみてみたのですが、
    特徴量は54あるのに52個しか出力されてきませんでした。
    デフォルトではすべて出るようになっているのになぜなんでしょう。。。
    ずぶの素人でわけのわからない質問をしていると思います、すみません。

  4. @matatabipower

    Questioner

    また進捗があったのでご報告します。
    num_roundを増やしたらfeature importanceで拾われる特徴量が10個くらいになりました!!

  5. @matatabipower

    Questioner

    スコアを数値で出してみたところ、0のものは表示されないようだということがわかりました。
    本当にお世話になりました~~~!!!!ありがとうございました!!

  6. 中途半端な回答で終わってしまい申し訳無いです。
    しかし、自力で解決されたようでなによりです。

Your answer might help someone💌