web-dev-qa-db-ja.com

XGBoost plot_importanceに機能名が表示されない

私はXGBoostをPythonで使用しており、DMatrix dataで呼び出されるXGBoost train()関数を使用してモデルを正常にトレーニングしました。マトリックスは=から作成されましたPandasデータフレーム。列の機能名があります。

_Xtrain, Xval, ytrain, yval = train_test_split(df[feature_names], y, \
                                    test_size=0.2, random_state=42)
dtrain = xgb.DMatrix(Xtrain, label=ytrain)

model = xgb.train(xgb_params, dtrain, num_boost_round=60, \
                  early_stopping_rounds=50, maximize=False, verbose_eval=10)

fig, ax = plt.subplots(1,1,figsize=(10,10))
xgb.plot_importance(model, max_num_features=5, ax=ax)
_

xgboost.plot_importance()関数を使用して機能の重要性を確認したいのですが、結果のプロットには機能名が表示されません。代わりに、以下に示すように、機能は_f1_、_f2_、_f3_などとしてリストされます。

enter image description here

問題は、元のPandas=データフレームをDMatrixに変換したことだと思います。機能の重要度プロットに表示されるように機能名を適切に関連付けるにはどうすればよいですか?

18

feature_namesを作成するときにxgb.DMatrixパラメーターを使用する場合

dtrain = xgb.DMatrix(Xtrain, label=ytrain, feature_names=feature_names)
19
piRSquared

train_test_splitは、データフレームをnumpy配列に変換しますが、これには列情報がありません。

@piRSquaredが提案したことを行い、機能をパラメーターとしてDMatrixコンストラクターに渡すことができます。または、train_test_splitから返されたnumpy配列をデータフレームに変換してから、コードを使用できます。

Xtrain, Xval, ytrain, yval = train_test_split(df[feature_names], y, \
                                    test_size=0.2, random_state=42)

# See below two lines
X_train = pd.DataFrame(data=Xtrain, columns=feature_names)
Xval = pd.DataFrame(data=Xval, columns=feature_names)

dtrain = xgb.DMatrix(Xtrain, label=ytrain)
7
Vivek Kumar

Scikit-learnラッパーを使用している場合、基盤となるXGBoost Boosterにアクセスし、scikitモデルの代わりに機能名を設定する必要があります。

model = joblib.load("your_saved.model")
model.get_booster().feature_names = ["your", "feature", "name", "list"]
xgboost.plot_importance(model.get_booster())
7
Darrrrrren

Scikit-Learn Wrapperインターフェース「XGBClassifier」を使用すると、plot_importanceはクラス「matplotlib Axes」を返します。したがって、axes.set_yticklabelsを使用できます。

plot_importance(model).set_yticklabels(['feature1','feature2'])

2
Vincent M.K

feature_namesで遊んでいるときに見つけた別の方法。それをいじりながら、私は現在実行しているXGBoost v0.80で動作するこれを書きました。

## Saving the model to disk
model.save_model('foo.model')
with open('foo_fnames.txt', 'w') as f:
    f.write('\n'.join(model.feature_names))

## Later, when you want to retrieve the model...
model2 = xgb.Booster({"nthread": nThreads})
model2.load_model("foo.model")

with open("foo_fnames.txt", "r") as f:
    feature_names2 = f.read().split("\n")

model2.feature_names = feature_names2
model2.feature_types = None
fig, ax = plt.subplots(1,1,figsize=(10,10))
xgb.plot_importance(model2, max_num_features = 5, ax=ax)

したがって、これはfeature_namesを個別に保存し、後で追加し直します。何らかの理由で、値がNoneであっても、feature_typesも初期化する必要があります。

1