短小
我试图用它tuneRF
来寻找函数的最佳mtry
值,randomForest
但是我发现答案是非常不稳定的,并且会随着运行/运行种子的不同而变化。我将运行一个循环,以查看它如何在大量运行中发生变化,但是无法提取出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
但种子= 3mtry=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
但种子= 3mtry=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
非常感谢您提供的任何帮助(甚至对与之相关的一般评论)。对于碰巧偶然寻求tuneRF
帮助的其他人,我也发现这篇文章很有帮助。
R:tuneRF函数的行为不清楚(randomForest包)
值得一提的是,较小功能集(具有非包含性功能)的最佳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)