Ответ 1
Вы хотите использовать параметр feature_names
при создании xgb.DMatrix
dtrain = xgb.DMatrix(Xtrain, label=ytrain, feature_names=feature_names)
Я использую 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. Как я могу связать имена объектов так, чтобы их отображал график важности функции?
Вы хотите использовать параметр feature_names
при создании xgb.DMatrix
dtrain = xgb.DMatrix(Xtrain, label=ytrain, feature_names=feature_names)
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)
Если вы используете оболочку 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())
Альтернативный способ, который я нашел, пока играл с 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
.
С интерфейсом Scikit-Learn Wrapper "XGBClassifier" plot_importance возвращает класс "Оси matplotlib". Таким образом, мы можем использовать axes.set_yticklabels.
plot_importance(model).set_yticklabels(['feature1','feature2'])