R tuneRF 不稳定,如何优化?
Posted
技术标签:
【中文标题】R tuneRF 不稳定,如何优化?【英文标题】:R tuneRF unstable, how to optimize? 【发布时间】:2016-03-06 03:12:58 【问题描述】:短片
我正在尝试使用 tuneRF
为我的 randomForest
函数找到最佳的 mtry
值,但我发现答案非常不稳定,并且会随着运行/不同种子的运行而变化。我会运行一个循环来查看它在大量运行中是如何变化的,但我无法提取出哪个mtry
具有最低的OOB 错误。
漫长的
我有一个data.frame
,它有八个功能,但其中两个功能是包容性的,这意味着一个中的所有信息都是另一个的子集。例如,一个特征可能是因子 A ~c("animal', "fish")
,而另一个特征可能是因子 B ~c("dog", "cat", "salmon", "trout")
。因此,所有的狗和猫都是动物,所有的鲑鱼和鳟鱼都是鱼。这两个变量比其他六个变量中的任何一个都重要得多。因此,如果我运行 3 个森林,一个使用 A,一个使用 B,一个使用 A & B,最后一个似乎是最好的。我怀疑这是因为 A 和/或 B 是如此重要,以至于通过将两者都包括在内,我有双倍的机会随机选择它们作为初始特征。我进一步怀疑我不应该允许这种情况发生,我应该排除 A 作为一个因素,但我找不到任何实际说明这一点的文献。
无论如何,要回到正轨。我有两个数据集tRFx
和tRFx2
,其中第一个包含 7 个特征,包括 B 但不包含 A,第二个包含 8 个具有 A 和 B 的特征。我正在尝试查看最佳 mtry
的用途这两个独立的模型,然后是它们相对于彼此的表现。问题是tuneRF
似乎,至少在这种情况下,非常不稳定。
对于第一个数据集,(包括特征 B 但不包括 A)
> set.seed(1)
> tuneRF(x = tRFx, y = tRFy, nTreeTry = 250, stepFactor = 1.5, improve = 0.01)
mtry = 2 OOB error = 17.73%
Searching left ...
Searching right ...
mtry = 3 OOB error = 17.28%
0.02531646 0.01
mtry = 4 OOB error = 18.41%
-0.06493506 0.01
mtry OOBError
2.OOB 2 0.1773288
3.OOB 3 0.1728395
4.OOB 4 0.1840629
> set.seed(3)
> tuneRF(x = tRFx, y = tRFy, nTreeTry = 250, stepFactor = 1.5, improve = 0.01)
mtry = 2 OOB error = 18.07%
Searching left ...
Searching right ...
mtry = 3 OOB error = 18.18%
-0.00621118 0.01
mtry OOBError
2.OOB 2 0.1806958
3.OOB 3 0.1818182
即种子 1 mtry=3
但种子 = 3 mtry=2
对于第二个数据集(包括特征 A 和 B)
> set.seed(1)
> tuneRF(x = tRFx2, y = tRFy, nTreeTry = 250, stepFactor = 1.5, improve = 0.01)
mtry = 3 OOB error = 17.51%
Searching left ...
mtry = 2 OOB error = 16.61%
0.05128205 0.01
Searching right ...
mtry = 4 OOB error = 16.72%
-0.006756757 0.01
mtry OOBError
2.OOB 2 0.1661055
3.OOB 3 0.1750842
4.OOB 4 0.1672278
> set.seed(3)
> tuneRF(x = tRFx2, y = tRFy, nTreeTry = 250, stepFactor = 1.5, improve = 0.01)
mtry = 3 OOB error = 17.4%
Searching left ...
mtry = 2 OOB error = 18.74%
-0.07741935 0.01
Searching right ...
mtry = 4 OOB error = 17.51%
-0.006451613 0.01
mtry OOBError
2.OOB 2 0.1874299
3.OOB 3 0.1739618
4.OOB 4 0.1750842
即种子 1 mtry=2
但种子 = 3 mtry=3
我打算运行一个循环来查看在大量模拟中哪个mtry
是最佳的,但不知道如何从每次迭代中捕获最佳mtry
。
我知道我可以使用
> set.seed(3)
> min(tuneRF(x = tRFx2, y = tRFy, nTreeTry = 250, stepFactor = 1.5, improve = 0.01))
mtry = 3 OOB error = 17.4%
Searching left ...
mtry = 2 OOB error = 18.74%
-0.07741935 0.01
Searching right ...
mtry = 4 OOB error = 17.51%
-0.006451613 0.01
[1] 0.1739618
但我不想捕获 OOB 错误 (0.1739618),而是最佳 mtry
(3)。
非常感谢任何帮助(甚至是与 tuneRF
相关的任何问题的一般 cmets)。对于碰巧发现此问题并寻求tuneRF
帮助的其他人,我也发现这篇文章很有帮助。
R: unclear behaviour of tuneRF function (randomForest package)
值得一提的是,较小的特征集(具有非包容性特征)的最佳 mtry 似乎是 3,而较大的特征集只有 2,这最初是违反直觉的,但是当您考虑到包容性的性质时A 和 B 确实/可能有意义。
【问题讨论】:
我没有你的具体问题的答案,但我可以说A
中的信息并不是你所说的B
的子集。例如,fish
可能等价于salmon|trout
,但与单独使用它们中的任何一个都不相同。不亚于模型效果与回归模型中的任何一个项相同。因此,您有正当理由同时包含这两个功能。
感谢@Special Sauce,非常感谢您的意见。这对我来说很有意义。
【参考方案1】:
在您选择的 mtry 的这种情况下(和其他情况),性能没有太大差异。只有当你不想赢得赢家通吃的 kaggle 比赛时,你可能还会将许多其他学习算法融合到一个庞大的集合中。在实践中,您会得到几乎相同的预测。
当您测试这么少的参数组合时,您不需要逐步优化。只需将它们全部尝试并重复多次以找出哪个 mtry 稍微好一点。
在我使用 tuneRF 的所有时间里,我一直很失望。每次我最终编写自己的逐步优化或只是多次尝试所有组合时。
mtry 与 oob-err 不必是具有单个最小值的平滑曲线,但应观察总体趋势。我很难判断最小值是由于噪音还是一般趋势。
我写了一个做固体 mtry 筛选的例子。这次筛选的结论是没有太大区别。 mtry=2 似乎最好,计算起来会稍微快一些。无论如何,默认值都是 mtry=floor(ncol(X)/3)。
library(mlbench)
library(randomForest)
data(PimaIndiansDiabetes)
y = PimaIndiansDiabetes$diabetes
X = PimaIndiansDiabetes
X = X[,!names(X)%in%"diabetes"]
nvar = ncol(X)
nrep = 25
rf.list = lapply(1:nvar,function(i.mtry)
oob.errs = replicate(nrep,
oob.err = tail(randomForest(X,y,mtry=i.mtry,ntree=2000)$err.rate[,1],1))
)
plot(replicate(nrep,1:nvar),do.call(rbind,rf.list),col="#12345678",
xlab="mtry",ylab="oob.err",main="tuning mtry by oob.err")
rep.mean = sapply(rf.list,mean)
rep.sd = sapply(rf.list,sd)
points(1:nvar,rep.mean,type="l",col=3)
points(1:nvar,rep.mean+rep.sd,type="l",col=2)
points(1:nvar,rep.mean-rep.sd,type="l",col=2)
【讨论】:
以上是关于R tuneRF 不稳定,如何优化?的主要内容,如果未能解决你的问题,请参考以下文章