I use xgboost.XGBClassifier for a multiclass classification problem, and I want to adjust the algorithm such way as to make the metric f1_score(average='macro') higher. I tried changing a parameter objective of XGBClassifier and made the following:

from sklearn.metrics import f1_score
def f1_macro(y_true, y_pred):
    return f1_score(y_true, y_pred, average='macro')
xg_tree = xgb.XGBClassifier(max_depth = 3, n_estimators = 1000, booster = 'gbtree',
       n_jobs=-1, subsample=1, learning_rate=0.005, objective = f1_macro, num_cass = 3)
xg_tree.fit(X_train, y_train)

But I have a mistake

ValueError: Classification metrics can't handle a mix of multiclass and continuous-multioutput targets

As I've read the custom objective function should output the value of a gradient and a hessian.

Could you please help me to figure out what way I should rewrite my objective function to fix this mistake?

Thanks in advance!


closed as off-topic by mdewey, Michael Chernick, kjetil b halvorsen, jld, Stephan Kolassa Mar 20 '18 at 8:53

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question appears to be off-topic because EITHER it is not about statistics, machine learning, data analysis, data mining, or data visualization, OR it focuses on programming, debugging, or performing routine operations within a statistical computing platform. If the latter, you could try the support links we maintain." – mdewey, Michael Chernick, kjetil b halvorsen, jld, Stephan Kolassa
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    $\begingroup$ You cannot use non-differentiable objective functions in gradient boosting, since the algorithm explicitly depends on knowing the gradient of whatever you are optimizing. Instead, you need to optimize log-loss to create a model that predicts probabilities, and then you can optimize whatever hard classification metric you want to by tuning the threshold you apply to probabilities to make class assignments. $\endgroup$ – Matthew Drury Mar 18 '18 at 16:20
  • $\begingroup$ @MatthewDrury Thank you for your answer. Do you mean, that I should firstly fit classifier, using mlogloss as an objective function. After that I should somehow pick up the value of threshold( which is used to identify what class an object belongs to ) such way as to maximize f_score? $\endgroup$ – D F Mar 18 '18 at 16:33
  • $\begingroup$ Yes, that's the standard procedure. $\endgroup$ – Matthew Drury Mar 18 '18 at 16:53