XGBoost plot_importance не показывает имена функций

Я использую XGBoost с Python и успешно обучил модель, используя функцию XGBoost train(), называемую данными DMatrix. Матрица была создана из фрейма 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 и т.д., Как показано ниже.

введите описание изображения здесь

Я думаю, проблема в том, что я преобразовал исходный кадр данных Pandas в DMatrix. Как я могу связать имена объектов так, чтобы их отображал график важности функции?

Ответ 1

Вы хотите использовать параметр feature_names при создании xgb.DMatrix

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

Ответ 2

train_test_split преобразует dataframe в массив numpy, который больше не имеет информации о столбцах.

Либо вы можете сделать то, что предложил @piRSquared, и передать функции в качестве параметра в конструктор DMatrix. Или же вы можете преобразовать массив numpy, возвращаемый из train_test_split в Dataframe, а затем использовать свой код.

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)

Ответ 3

Если вы используете оболочку 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())

Ответ 4

Альтернативный способ, который я нашел, пока играл с 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 и добавляет их позже. По некоторым причинам feature_types также необходимо инициализировать, даже если значение равно None.

Ответ 5

С интерфейсом Scikit-Learn Wrapper "XGBClassifier" plot_importance возвращает класс "Оси matplotlib". Таким образом, мы можем использовать axes.set_yticklabels.

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