短小

我正在尝试使用tuneRF为我的mtry函数找到最佳的randomForest值,但是我发现答案非常不稳定,并且随着运行/运行种子的不同而变化。我将运行一个循环,以查看它如何在大量运行中发生变化,但无法提取出具有最低OOB错误的mtry

长龙

我有一个具有八个功能的data.frame,但是其中两个功能是包含性的,这意味着一个中的所有信息都是另一个的子集。例如,一个特征可能是因子A〜c("animal', "fish"),而另一个特征可能是因子B〜c("dog", "cat", "salmon", "trout")。因此,所有的猫狗都是动物,所有的鲑鱼和鳟鱼都是鱼。这两个变量远比其他六个变量重要。因此,如果我运行3个林,一个使用A,一个使用B,另一个使用A和B,则最后一个似乎表现最好。我怀疑这是因为A和/或B如此重要,以至于通过同时包含这两者,我有两倍的机会随机选择它们作为初始特征。我进一步怀疑,我不应该允许这种情况发生,我应该把A排除在外,但是我找不到任何实际的说法。

无论如何回到正轨。我有两个数据集tRFxtRFx2,第一个数据集包含7个特征,包括B但不包含A;第二个数据集包含8个特征,同时包含A和B。这两个单独的模型,以及它们相对彼此的表现。问题是,至少在这种情况下,mtry似乎非常不稳定。

对于第一个数据集,(包括特征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 tuneRF但种子= 3 mtry=3

对于第二个数据集(包括功能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=2

我打算运行一个循环,以查看在大量仿真中哪个mtry=3是最佳的,但不知道如何从每次迭代中捕获最佳的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)。

非常感谢任何帮助(甚至对与mtry相关的任何问题的一般评论)。对于碰巧偶然找到tuneRF帮助的其他人,我也发现这篇文章很有帮助。
R: unclear behaviour of tuneRF function (randomForest package)

值得一提的是,较小功能集(具有非包含性功能)的最佳mtry为3,较大功能集仅为2,这最初是反直观的,但考虑到A和B的包含性它确实/可能有意义。

最佳答案

在这种情况下(和其他情况下),您选择的尝试性能没有太大差异。只有当您不想赢得赢家全力以赴的kaggle比赛时,您才可能在一个巨大的合奏中将许多其他学习算法融合在一起。实际上,您得到的预测几乎相同。
测试如此少的参数组合时,无需逐步优化。只需尝试所有步骤,然后重复多次以找出哪种方法更好。
我一直使用tuneRF感到很失望。每次我最终编写自己的逐步优化或多次尝试所有组合时。
尽管应观察到总体趋势,但mtry与oob-err不必是一条具有单个最小值的平滑曲线。我很难说出最小值是由于噪声还是总体趋势引起的。


我写了一个进行固态晶体筛选的例子。此筛选的结论不会有太大差异。 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 - R tuneRF不稳定,如何优化?-LMLPHP

07-28 00:11