短
我正在尝试使用tuneRF
为我的mtry
函数找到最佳randomForest
值,但我发现答案非常不稳定,并且随着run to run /更改不同的种子。我会运行一个循环来查看它是如何在大量运行中发生变化但是无法提取哪个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的特征。我正在尝试查看最佳{ {1}}用于这两个单独的模型,然后是它们相对于彼此的表现。问题是mtry
似乎,至少在这种情况下,非常不稳定。
对于第一个数据集,(包括特征B但不包括A)
tuneRF
即种子1 > 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
但种子= 3 mtry=3
对于第二个数据集(包括特征A和B)
mtry=2
即种子1 > 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
但种子= 3 mtry=2
我打算运行一个循环来查看哪个mtry=3
在大量模拟中是最优的,但不知道如何从每次迭代中捕获最佳mtry
。
我知道我可以使用
mtry
但我不想捕获OOB错误(0.1739618),而是最佳> 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
(3)。
任何帮助(甚至是与mtry
相关的一般评论)都非常感谢。对于碰巧偶然发现tuneRF
帮助的其他人,我也发现这篇文章很有帮助。
R: unclear behaviour of tuneRF function (randomForest package)
对于它的价值而言,较小的特征集(具有非包含特征)的最佳mtry似乎是3,而较大的特征集只有2,这最初是反直觉但是当你考虑到包容性时A和B确实/可能有意义。
答案 0 :(得分:4)
在这种情况下(以及其他)你选择mtry的表现没有太大差异。只有当你不想赢得胜利者所有人的争吵竞赛时,你才可能在一个巨大的整体中融合许多其他学习算法。在实践中,你得到几乎相同的预测。
测试如此少的参数组合时,不需要逐步优化。试试这些并重复多次以确定哪个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)