Search code examples
scikit-learnxgboost

XGBoost: While using the `eval_set` in .fit causing Error


I'm trying to train the model using Xgboost. The code is doing split using KFold. And for each fold, it's running the Xgboost model using fit. Within the fit function, I'm trying to evaluate both train and valid data to check if the errors. And then doing the prediction in test set.

I'm running the following code using Xgboost.

kf = GroupKFold(n_splits=4)

for trn_idx, test_idx in kf.split(X, groups=X.year) :
    x_train, x_valid = X.iloc[trn_idx], X.iloc[test_idx]
    y_train, y_valid = y.iloc[trn_idx], y.iloc[test_idx]
    
    
    xgb_model = xgb.XGBRegressor( 
                        booster = 'dart',
                        eta = 0.1,
                        gamma = 0,
                        colsample_bytree = 0.7,
                       n_estimators  = 1200,
                       max_depth     = 1,
                           reg_alpha = 1.1,
                           reg_lambda = 1.1,
                           subsample = 0.03,
                       eval_metric=my_smape)
    
    xgb_model.fit(x_train, y_train,
        eval_set=[(x_train, y_train), (x_valid,y_valid)], early_stopping_rounds=20,
                    verbose=True)

But I'm getting the following error. I checked this doc, and my code is according to the doc. Can someone please help me find the solution?

AttributeError                            Traceback (most recent call last)
<ipython-input-38-81b11a21472c> in <module>
     23                        eval_metric=my_smape)
     24 
---> 25     xgb_model.fit(x_train, y_train,
     26         eval_set=[(x_valid,y_valid)], early_stopping_rounds=20,
     27                         verbose=True)

D:\Anaconda\lib\site-packages\xgboost\core.py in inner_f(*args, **kwargs)
    573         for k, arg in zip(sig.parameters, args):
    574             kwargs[k] = arg
--> 575         return f(**kwargs)
    576 
    577     return inner_f

D:\Anaconda\lib\site-packages\xgboost\sklearn.py in fit(self, X, y, sample_weight, base_margin, eval_set, eval_metric, early_stopping_rounds, verbose, xgb_model, sample_weight_eval_set, base_margin_eval_set, feature_weights, callbacks)
    959             xgb_model, eval_metric, params, early_stopping_rounds, callbacks
    960         )
--> 961         self._Booster = train(
    962             params,
    963             train_dmatrix,

D:\Anaconda\lib\site-packages\xgboost\core.py in inner_f(*args, **kwargs)
    573         for k, arg in zip(sig.parameters, args):
    574             kwargs[k] = arg
--> 575         return f(**kwargs)
    576 
    577     return inner_f

D:\Anaconda\lib\site-packages\xgboost\training.py in train(params, dtrain, num_boost_round, evals, obj, feval, maximize, early_stopping_rounds, evals_result, verbose_eval, xgb_model, callbacks, custom_metric)
    180             break
    181         bst.update(dtrain, i, obj)
--> 182         if cb_container.after_iteration(bst, i, dtrain, evals):
    183             break
    184 

D:\Anaconda\lib\site-packages\xgboost\callback.py in after_iteration(self, model, epoch, dtrain, evals)
    237             for _, name in evals:
    238                 assert name.find('-') == -1, 'Dataset name should not contain `-`'
--> 239             score: str = model.eval_set(evals, epoch, self.metric, self._output_margin)
    240             splited = score.split()[1:]  # into datasets
    241             # split up `test-error:0.1234`

D:\Anaconda\lib\site-packages\xgboost\core.py in eval_set(self, evals, iteration, feval, output_margin)
   1860         if feval is not None:
   1861             for dmat, evname in evals:
-> 1862                 feval_ret = feval(
   1863                     self.predict(dmat, training=False, output_margin=output_margin), dmat
   1864                 )

D:\Anaconda\lib\site-packages\xgboost\sklearn.py in inner(y_score, dmatrix)
     99     def inner(y_score: np.ndarray, dmatrix: DMatrix) -> Tuple[str, float]:
    100         y_true = dmatrix.get_label()
--> 101         return func.__name__, func(y_true, y_score)
    102     return inner
    103 

AttributeError: '_PredictScorer' object has no attribute '__name__'

Solution

  • It looks like you've run make_scorer() on your custom metric. Try supplying the original function as eval_metric instead, this should fix the issue.