理解R中xgboost的num_classes

时间:2016-03-18 14:07:44

标签: r xgboost

我在弄清楚如何正确设置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 个答案:

答案 0 :(得分:6)

标签必须在[0,num_class]中 在您的脚本中,在y<-y-1

之前添加model <-...

答案 1 :(得分:3)

我也遇到了这个相当奇怪的问题。在我的班级中,似乎没有正确地对标签进行编码

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

将标签重新编码为整数 nd,然后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
)

例如。

答案 2 :(得分:1)

我看到了同样的错误,我的问题是我使用的eval_metric仅在我的数据具有二进制标签时才用于多类标签。有关所有选项的列表,请参见Learning Class Parameters section of the XGBoost docs中的eval_metric

答案 3 :(得分:0)

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

教程说:

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

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

label = as.integer(high_end)