为何set.seed调用时机不同,caret::createFolds生成的折结果不同?
为什么caret::createFolds在单次设置种子后多次调用会生成不同结果?
这不是caret::createFolds不遵循随机种子,而是R语言随机数生成机制的正常表现——R的随机数生成器是状态依赖的:
set.seed()的作用是把随机数生成器重置到一个固定的初始状态- 任何需要生成随机数的函数(包括
createFolds内部的分层抽样随机逻辑),都会消耗当前的随机数状态,让生成器前进到下一个新状态
对应你的两种场景:
仅首次调用前设置一次
set.seed(18)
第一次调用createFolds时,用的是初始状态的随机数,调用完成后随机数生成器的状态已经改变;后续每次调用createFolds,都会基于当前更新后的状态生成随机数,所以每一次的折分组结果都不一样。但因为整个代码块开头的种子是固定的,重复运行这段代码时,随机数生成器的状态变化路径完全一致,所以你会得到同一组不同的结果(也就是你看到的212213、222311这一串固定序列)。每次调用前都设置
set.seed(18)
每次调用createFolds前,都把随机数生成器重置到同一个初始状态,所以每次createFolds用到的随机数都是完全相同的,自然生成的交叉验证折结果也完全一致。
代码验证
你的示例1:
set.seed(18) head(caret::createFolds(mtcars$cyl, k=3, list=FALSE)) head(caret::createFolds(mtcars$cyl, k=3, list=FALSE)) head(caret::createFolds(mtcars$cyl, k=3, list=FALSE)) head(caret::createFolds(mtcars$cyl, k=3, list=FALSE)) head(caret::createFolds(mtcars$cyl, k=3, list=FALSE))
每次调用createFolds都推进了随机数状态,所以结果依次变化,但重复运行整段代码,得到的序列是固定的。
示例2:
lapply(1:5, function(x) { set.seed(18) head(caret::createFolds(mtcars$cyl, k=3, list=FALSE)) })
每次循环都重置种子,所以每次createFolds都从相同初始状态生成随机数,结果全是2 1 2 2 1 3。
一句话总结:createFolds完全遵循随机种子,只是你得理解R随机数生成的状态式逻辑——种子不是“锁定”随机结果,而是给出一个固定的随机数生成起点,每用一次随机数,起点就会往前挪。
内容的提问来源于stack exchange,提问作者user29444121
相关产品推荐
相关产品推荐

