web-dev-qa-db-fra.com

XGBoost plot_importance n'affiche pas les noms des fonctionnalités

J'utilise XGBoost avec Python et j'ai réussi à former un modèle à l'aide de la fonction XGBoost train() appelée sur des données DMatrix. La matrice a été créée à partir d’un cadre de données Pandas, qui contient des noms d’entité pour les colonnes.

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)

Je veux maintenant voir l'importance de la fonctionnalité à l'aide de la fonction xgboost.plot_importance(), mais le tracé obtenu ne montre pas les noms des fonctionnalités. À la place, les fonctionnalités sont répertoriées sous la forme f1, f2, f3, etc., comme indiqué ci-dessous.

 enter image description here

Je pense que le problème est que j'ai converti mon bloc de données Pandas original en un DMatrix. Comment puis-je associer correctement les noms d'entités afin que le tracé de leur importance les montre?

13

Vous souhaitez utiliser le paramètre feature_names lors de la création de votre xgb.DMatrix

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

train_test_split convertira le dataframe en un tableau numpy qui n’a plus d’informations sur les colonnes.

Soit vous pouvez faire ce que @piRSquared a suggéré et transmettre les fonctionnalités en tant que paramètre au constructeur DMatrix. Sinon, vous pouvez convertir le tableau numpy renvoyé par le train_test_split en un fichier de données, puis utiliser votre code.

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)
6
Vivek Kumar

Une autre manière que je trouvais tout en jouant avec feature_names. Tout en jouant avec, j'ai écrit ceci qui fonctionne sur XGBoost v0.80 que je cours actuellement.

## 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)

Il s’agit donc d’enregistrer le code feature_names séparément et de le rajouter ultérieurement. Pour une raison quelconque, feature_types doit également être initialisé, même si la valeur est None.

0
Peter VanderMeer