15

我在弄清楚如何正确设置 xgboost 的 num_classes 时遇到了很多麻烦。

我有一个使用 Iris 数据的示例

df <- iris

y <- df$Species
num.class = length(levels(y))
levels(y) = 1:num.class
head(y)

df <- df[,1:4]

y <- as.matrix(y)
df <- as.matrix(df)

param <- list("objective" = "multi:softprob",    
          "num_class" = 3,    
          "eval_metric" = "mlogloss",    
          "nthread" = 8,   
          "max_depth" = 16,   
          "eta" = 0.3,    
          "gamma" = 0,    
          "subsample" = 1,   
          "colsample_bytree" = 1,  
          "min_child_weight" = 12)

model <- xgboost(param=param, data=df, label=y, nrounds=20)

这会返回一个错误

Error in xgb.iter.update(bst$handle, dtrain, i - 1, obj) : 
SoftmaxMultiClassObj: label must be in [0, num_class), num_class=3 but found 3 in label

如果我将 num_class 更改为 2,我会得到同样的错误。如果我将 num_class 增加到 4,那么模型就会运行,但我会得到 600 个预测概率,这对于 4 个类是有意义的。

我不确定我是否犯了错误,或者我是否无法理解 xgboost 的工作原理。任何帮助,将不胜感激。

4

4 回答 4

9

标签必须在脚本中的 [0, num_class)y<-y-1之前添加model <-...

于 2016-03-18T15:13:49.120 回答
4

我看到了同样的错误,我的问题是eval_metric当我的数据有二进制标签时,我使用的只是用于多类标签。有关所有选项的列表,请参阅XGBoost 文档eval_metric学习类参数部分。

于 2018-08-13T16:49:12.143 回答
4

我也遇到了这个相当奇怪的问题。在我的课堂上,这似乎是标签编码不正确的结果。

首先,使用带有 N 个类作为标签的字符串向量,我只能通过设置num_class= N + 1 来运行算法。但是,这个结果是没有用的,因为我只有 N 个实际类和 N+1 个预测概率桶.

将标签重新编码为整数,然后num_class在设置为 N 时工作正常。

# Convert classes to integers for xgboost
class <- data.table(interest_level=c("low", "medium", "high"), class=c(0,1,2))
t1    <- merge(t1, class, by="interest_level", all.x=TRUE, sort=F)

param <- list(booster="gbtree",
              objective="multi:softprob",
              eval_metric="mlogloss",
              #nthread=13,
              num_class=3,
              eta_decay = .99,
              eta = .005,
              gamma = 1,
              max_depth = 4,
              min_child_weight = .9,#1,
              subsample = .7,
              colsample_bytree = .5
)

例如。

于 2017-05-10T20:14:47.460 回答
0

我遇到了这个问题,结果发现我试图从已经以 0 和 1 为单位的预测变量中减去 1。这可能是一个新手错误,但万一其他人使用二进制响应变量遇到这个问题已经是 0 和 1,这是需要注意的。

教程说:

label = as.integer(iris$Species)-1

什么对我有用(响应是高端):

label = as.integer(high_end)
于 2019-11-21T05:17:32.400 回答