R-MLR:使用“makeTuneControlRandom”为包装学习器调整超参数
R-MLR : tuning hyper parameters using ' makeTuneControlRandom ' for a wrapped learner
根据 及其评论中提出的建议,我试图为 makeTuneControlRandom
函数的 maxit
参数找到一个合适的值,这样当我缩小 lower:upper
间隔优化后的超参数不变。在这样做的过程中,我遇到了一个找不到原因的案例:
假设要调整的超参数是 max_depth
,它必须是一个整数。在第一步中,我定义搜索 space 如下:
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_depth
= 4 并且相应的混淆矩阵也不同(fp=33,fn=22)。为什么我无法重新找到相同的最佳值?这是由于包含的欠采样过程随机减少了我的 类 之一,所以剩余的观察结果在每个 运行 都会发生变化吗?如果是这样,我似乎永远找不到一个单一的调谐模型。我有什么可能的解决方案来克服这个问题?非常感谢。
今天看了你的问题,似乎你没有完全理解你"tune a model"时发生的事情,没有特别看调整方法(这里:随机搜索)。
我的回答只会解释一个特定的部分,但我强烈建议查阅有关一般统计学习/机器学习的文献。
Elements of Statistical Learning 是一个好的开始。
优化超参数
您要的是"tuning stability"。
在您的问题中,您想找到优化问题的局部最小值,并且假设您已经通过 50 次随机搜索尝试找到了它 (max_depth = 7
)。
然而,事实证明,如果您使用 maxit = 100
(100 次随机搜索尝试),您会得到另一个最优值。
这很好。
这样看:如果幸运的话,您可以在第一次尝试时找到局部最小值(即最大程度地减少错误的超参数设置)(!)。
如果你运气不好,你可能会尝试 10^6 次而找不到局部最小值。
问题是,您不知道局部最小值是多少。
你永远不会发现。
没有人会。
因此,可能会发生 "best setting" 对于 50 次尝试和 10^6 次尝试是相同的 - 或者在使用 50 次和 51 次尝试时它会有所不同。
关于您能够覆盖搜索的密集程度是否总是一个问题space。搜索 space 是 n 维的(n
是超参数的个数),n
越大,就越不可能找到相同数量的最优设置尝试。
寻找 "the best model"
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.
我不确定你在这里的确切意思,但这些问题可能指向交叉验证和 "finding the best model" 之间的常见误解。最近有几个问题都存在这些概念性问题:您没有在 CV 中搜索 "best model"。
CV 仅用于性能评估,每一折都是独一无二的,有自己的优化、特征选择等。
您不应在折叠内搜索任何内容 "best" 或尝试提取内容。
再次,我建议阅读一些文献,例如上面的参考资料,以便更好地了解您正在做的事情的全貌。
附录
- 您可能想要 post 此类纯粹关注 "why is something like XX" 和 "I am not fully getting what is happening in XY, can someone help me?" 的问题 https://stats.stackexchange.com 而不是 Whosebug。
- 考虑使用 mlr3 而不是 mlr,因为后者已于 2019 年 7 月被开发团队淘汰。
根据 makeTuneControlRandom
函数的 maxit
参数找到一个合适的值,这样当我缩小 lower:upper
间隔优化后的超参数不变。在这样做的过程中,我遇到了一个找不到原因的案例:
假设要调整的超参数是 max_depth
,它必须是一个整数。在第一步中,我定义搜索 space 如下:
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_depth
= 4 并且相应的混淆矩阵也不同(fp=33,fn=22)。为什么我无法重新找到相同的最佳值?这是由于包含的欠采样过程随机减少了我的 类 之一,所以剩余的观察结果在每个 运行 都会发生变化吗?如果是这样,我似乎永远找不到一个单一的调谐模型。我有什么可能的解决方案来克服这个问题?非常感谢。
今天看了你的问题,似乎你没有完全理解你"tune a model"时发生的事情,没有特别看调整方法(这里:随机搜索)。 我的回答只会解释一个特定的部分,但我强烈建议查阅有关一般统计学习/机器学习的文献。 Elements of Statistical Learning 是一个好的开始。
优化超参数
您要的是"tuning stability"。
在您的问题中,您想找到优化问题的局部最小值,并且假设您已经通过 50 次随机搜索尝试找到了它 (max_depth = 7
)。
然而,事实证明,如果您使用 maxit = 100
(100 次随机搜索尝试),您会得到另一个最优值。
这很好。
这样看:如果幸运的话,您可以在第一次尝试时找到局部最小值(即最大程度地减少错误的超参数设置)(!)。 如果你运气不好,你可能会尝试 10^6 次而找不到局部最小值。
问题是,您不知道局部最小值是多少。 你永远不会发现。 没有人会。 因此,可能会发生 "best setting" 对于 50 次尝试和 10^6 次尝试是相同的 - 或者在使用 50 次和 51 次尝试时它会有所不同。
关于您能够覆盖搜索的密集程度是否总是一个问题space。搜索 space 是 n 维的(n
是超参数的个数),n
越大,就越不可能找到相同数量的最优设置尝试。
寻找 "the best model"
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.
我不确定你在这里的确切意思,但这些问题可能指向交叉验证和 "finding the best model" 之间的常见误解。最近有几个问题都存在这些概念性问题:您没有在 CV 中搜索 "best model"。 CV 仅用于性能评估,每一折都是独一无二的,有自己的优化、特征选择等。 您不应在折叠内搜索任何内容 "best" 或尝试提取内容。
再次,我建议阅读一些文献,例如上面的参考资料,以便更好地了解您正在做的事情的全貌。
附录
- 您可能想要 post 此类纯粹关注 "why is something like XX" 和 "I am not fully getting what is happening in XY, can someone help me?" 的问题 https://stats.stackexchange.com 而不是 Whosebug。
- 考虑使用 mlr3 而不是 mlr,因为后者已于 2019 年 7 月被开发团队淘汰。