我正在尝试运行xgboost来解决一个功能非常嘈杂的问题,并且有兴趣停止基于我定义的自定义eval_metric的轮数。
基于领域知识,我知道当eval_metric (根据训练数据进行评估)超过某个特定值时,xgboost是过拟合的。我只想在特定的轮次上采用拟合的模型,不再继续。
实现这一目标的最佳方法是什么?
这在一定程度上符合提前停止的标准,但并不完全如此。
或者,是否有可能从中间轮获得模型?
这里有一个例子可以更好地用问题来解释。(使用xgboost帮助文档附带的玩具示例并使用默认的eval_metric)
library(xgboost)
data(agaricus.train, package='xgboost')
train <- agaricus.train
bstSparse <- xgboost(data = train$data, label = train$label, max.depth = 2, eta = 1, nthread = 2, nround = 5, objective = "binary:logistic")以下是输出
[0] train-error:0.046522
[1] train-error:0.022263
[2] train-error:0.007063
[3] train-error:0.015200
[4] train-error:0.007063现在让我们说,根据领域知识,我知道一旦训练误差低于0.015 (在这种情况下是第三轮),任何进一步的轮次都只会导致过度拟合。我如何在第三轮之后停止训练过程,并获得训练后的模型,以便在不同的数据集上使用它进行预测?
我需要在许多不同的数据集上运行训练过程,并且我不知道可能需要训练多少轮才能使误差低于固定的数字,因此我无法将nround参数设置为预定值。我唯一的直觉是,一旦训练误差低于一个数字,我就需要停止进一步的训练。
发布于 2017-01-25 09:28:49
如果没有您尝试过的任何代码或您正在使用的任何数据,则尝试如下所示:
require(xgboost)
library(Metrics) # for rmse to calculate errors
# Assume you have a training set db.train and have some
# feature indices of interest and a test set db.test
predz <- c(2, 4, 6, 8, 10, 12)
predictors <- names(db.train[, predz])
# you have some response you are interested in
outcomeName <- "myLabel"
# you may like to include for testing some other parameters like:
# eta, gamma, colsample_bytree, min_child_weight
# here we look at depths from 1 to 4 and rounds 1 to 100 but set your own values
smallestError <- 100 # set to some sensible value depending on your eval metric
for (depth in seq(1, 4, 1)) {
for (rounds in seq(1, 100, 1)) {
# train
bst <- xgboost(data = as.matrix(db.train[,predictors]),
label = db.train[,outcomeName],
max.depth = depth,
nround = rounds,
eval_metric = "logloss",
objective = "binary:logistic",
verbose=TRUE)
gc()
# predict
predictions <- as.numeric(predict(bst, as.matrix(db.test[, predictors]),
outputmargin = TRUE))
err <- rmse(as.numeric(db.test[, outcomeName]), as.numeric(predictions))
if (err < smallestError) {
smallestError = err
print(paste(depth,rounds,err))
}
}
} 您可以根据您的特定评估指标调整此代码,并将其打印出来以适合您的情况。类似地,当达到某个指定的轮数并满足您希望达到的条件时,您可以在代码中引入一个中断。
https://stackoverflow.com/questions/41816754
复制相似问题