已关注 my previous question及其评论中提到的建议,我试图为 makeTuneControlRandom
函数的 maxit
参数找到一个合适的值,以便当我收缩 lower:upper
间隔优化后的超参数不会改变。在这样做的过程中,我遇到了一个无法找到原因的案例:
我们假设要调整的 super 参数是 max_depth
,它必须是整数。在第一步中,我定义搜索空间如下:
set.seed(1365)
# define task
Task <- mlr::makeClassifTask(id = "classif.xgboost",
data = df,
target = "response",
weights = NULL,
positive = "yes",
check.data = TRUE,
blocking = folds)
# make a base learner
lrnBase <- makeLearner(cl = "classif.xgboost",
predict.type = "prob",
predict.threshold = NULL)
paramSet <- makeParamSet(makeIntegerParam(id = "max_depth", lower = 3, upper = 10))
和:
tuneControl <- makeTuneControlRandom(maxit = 50)
如您所见,3 到 10 之间的整数值为 3、4、5、6、7、8、10,总共表示 8 个数字 (< 50)。
我运行代码:
# make an undersample-wrapped learner
lrnUnder <- makeUndersampleWrapper(learner = lrnBase, usw.rate = 0.2, usw.cl = "no")
tuneControl <- makeTuneControlRandom(maxit = 50)
# resampling
resampin <- makeResampleDesc(method = "CV",
iters = 4L,
predict = "test")
# make a tuning-wrapped learner
lrnTune <- makeTuneWrapper(learner = lrnUnder,
resampling = resampin,
measures = fp,
par.set = paramSet,
control = tuneControl)
resampout.desc <- makeResampleDesc(method = "CV",
iters = length(levels(folds)),
predict = "both",
fixed = TRUE)
resampout <- makeResampleInstance(desc = resampout.desc, task = Task)
resamp <- mlr::resample(learner = lrnTune,
task = Task,
resampling = resampout, # outer
measures = f1,
models = FALSE,
extract = getTuneResult,
keep.pred = TRUE)
mdl <- mlr::train(learner = lrnTune, task = Task)
getTuneResult(mdl)
调整后的 max_depth
返回为 7,具有特定的混淆矩阵(fp=20,fn=20)。我预计,如果我增加 maxit
参数的值,调整算法仍应找到相同的最佳 max_depth
。因此,我将 maxit 设置为 100,令人惊讶的是它返回 max_深度 = 4,并且相应的混淆矩阵也不同(fp=33,fn=22)。为什么我无法重新找到相同的最佳值?这是由于包括欠采样过程随机减少了我的一个类,因此剩余的观察结果在每次运行时都会发生变化吗?如果是这样,我似乎永远找不到一个单一的调整模型。我可以采取哪些解决方案来克服这个问题?预先非常感谢。
最佳答案
今天阅读您的问题,似乎您没有完全理解“调整模型”时发生的情况,而不是特别关注调整方法(此处:随机搜索)。 我的回答只会解释一个特定部分,但我强烈建议查阅有关一般统计学习/机器学习的文献。 Elements of Statistical Learning是一个好的开始。
优化超参数
您要求的是“调整稳定性”。
在您的问题中,您希望找到优化问题的局部最小值,并且您假设您已通过 50 次随机搜索尝试找到了它 (max_depth = 7
)。
然而,事实证明,如果您使用 maxit = 100
(100 次随机搜索尝试),您将获得另一个最佳值。
这完全没问题。
这样看:如果幸运的话,您可以在第一次尝试时找到局部最小值(即最大程度地减少错误的超参数设置)(!)。 如果运气不好,您可能尝试 10^6 次都找不到局部最小值。
问题是,你不知道局部最小值是多少。 你永远不会发现。 没有人会这么做。 因此,可能会发生 50 次尝试和 10^6 次尝试的“最佳设置”相同的情况 - 或者在使用 50 次和 51 次尝试时它会有所不同。
这始终是一个关于您能够覆盖搜索空间的密度的问题吗?搜索空间是 n 维的(n
是超参数的数量),n
越大,越不可能在相同的条件下找到最佳设置。尝试次数。
寻找“最佳模型”
Is this due to the including undersampling process that randomly reduces one of my classes so the remaining observations change at every run ? If so, it seems that I can never find one single tuned model.
我不确定你在这里的确切意思,但这些问题可能指出交叉验证和“寻找最佳模型”之间的常见误解。最近有几个问题都存在这些概念问题:您不会在简历中搜索“最佳模型”。 CV 仅用于性能评估,每次折叠都是独一无二的,有自己的优化、特征选择等。 您不应该在折叠中搜索任何“最佳”内容或尝试提取某些内容。
再次,我建议您阅读一些文献,例如上面的引用文献,以更好地了解您正在做的事情的整体情况。
附录
- 您可能想发布这样的问题,这些问题纯粹集中于“为什么是 XX 之类的东西”和“我没有完全了解 XY 中发生的情况,有人可以帮助我吗?”上https://stats.stackexchange.com而不是在 Stackoverflow 上。
- 考虑使用mlr3而不是 mlr,因为后者已于 2019 年 7 月被开发团队淘汰。
关于hyperparameters - R-MLR : tuning hyper parameters using ' makeTuneControlRandom ' for a wrapped learner,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59460902/