我在弄清楚如何正确设置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是如何工作的。任何帮助,将不胜感激。
答案 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)