XGBoost 自定义评估函数导致“无法强制类型闭包到类型向量”

Posted

技术标签:

【中文标题】XGBoost 自定义评估函数导致“无法强制类型闭包到类型向量”【英文标题】:XGBoost custom evaluation function causing "cannot coerce type closure to vector of type" 【发布时间】:2020-08-05 11:28:07 【问题描述】:

我尝试了许多不同的方法,但无法摆脱此错误消息。看不出我的代码与许多其他脚本有何不同。

y_train = train$y
train$y = c()
train= as.matrix(train)

train = xgb.DMatrix(data = train, label = y_train)

MSE = function(yhat,train)

   y = getinfo(train, "label")
   err = mean((y-yhat)^2)
   return(list(metric = "RMSE", value = err))



params = list(
  eta = 0.1,
  max_depth = 3,
  tweedie_variance_power = 1.5,
  objective = "reg:tweedie",
  feval = MSE
)

model = xgb.cv(
  data = train,
  nfold = 3,
  params = params,
  nrounds = 2000
)

我收到以下错误:

  Error in as.character(x) : 
  cannot coerce type 'closure' to vector of type 'character'

我发现回溯有点奇怪(见下文)。如果我删除 fevl 并使用内置的 nloglike eval 指标,我会使用自定义折叠,并且 xgb.cv 是可运行的。

  > traceback()
  7: FUN(X[[i]], ...)
  6: lapply(p, function(x) as.character(x)[1])
  5: `xgb.parameters<-`(`*tmp*`, value = params)
  4: xgb.Booster.handle(params, list(dtrain, dtest))
  3: FUN(X[[i]], ...)
  2: lapply(seq_along(folds), function(k) 
   dtest <- slice(dall, folds[[k]])
   dtrain <- slice(dall, unlist(folds[-k]))
   handle <- xgb.Booster.handle(params, list(dtrain, dtest))
   list(dtrain = dtrain, bst = handle, watchlist = list(train = dtrain, 
       test = dtest), index = folds[[k]])
   )
  1: xgb.cv(data = train, folds = folds, params = params, nrounds = 2000)

有什么建议吗?

【问题讨论】:

【参考方案1】:

根据您的需要,通过参数传递它,通过度量将起作用:

MSE = function(yhat,train)
   y = getinfo(train, "label")
   err = mean((y-yhat)^2)
   return(list(metric = "MSEerror", value = err))

params = list(
  eta = 0.1,
  max_depth = 3,
  tweedie_variance_power = 1.5,
  objective = "reg:tweedie",
eval_metric = MSE
)

举个例子:

library(xgboost)
train = mtcars
colnames(train)[1] = "y"
y_train = train$y
train$y = c()
train= as.matrix(train)
train = xgb.DMatrix(data = train, label = y_train)

model = xgb.cv(
  data = train,
  nfold = 3,
  params = params,
  nrounds = 2000
)

head(model$evaluation_log)
   iter train_MSEerror_mean train_MSEerror_std test_MSEerror_mean
1:    1            415.5046           20.92919           416.7119
2:    2            410.6576           20.78001           411.8646
3:    3            404.9321           20.59901           406.1391
4:    4            398.2114           20.38003           399.4192
5:    5            390.3808           20.11609           391.5902
6:    6            381.3338           19.79950           382.5464
   test_MSEerror_std
1:          62.18317
2:          61.77277
3:          61.28819
4:          60.71951
5:          60.05671
6:          59.29019

通过参数传递它有些奇怪(你可以在参数之外尝试,它会起作用),当我看到它是如何传递时可以稍后更新。

【讨论】:

谢谢!您描述的两种解决方案都可以解决问题。

以上是关于XGBoost 自定义评估函数导致“无法强制类型闭包到类型向量”的主要内容,如果未能解决你的问题,请参考以下文章

R语言构建xgboost模型:自定义损失函数(目标函数loss functionobject function)评估函数(evaluation function)

如何在 python 中为 xgboost 编写自定义评估指标?

R语言构建xgboost模型使用早停法训练模型(early stopping):自定义损失函数(目标函数,loss function)评估函数(evaluation function)

XGBoost 的自定义目标函数,包括外部数据列

xgboost 自定义评价函数(metric)与目标函数

自定义UDF函数vector_trans:遍历两个数组,将其转为目标向量数组(XGBoost模型)