简述
我在尝试使用tuneRF
来寻找我的randomForest
函数的最优mtry
值,但我发现结果非常不稳定,并且每次运行/使用不同的种子时都会发生变化。我本打算运行一个循环来观察在大量运行中它如何变化,但无法提取出哪个mtry
具有最低的OOB误差。
详细描述
我有一个data.frame
,其中包含八个特征,但其中两个特征是包含性的,意味着一个特征的信息是另一个特征的子集。例如,一个特征可能是因子A ~ c("animal", "fish")
,另一个特征是因子B ~ c("dog", "cat", "salmon", "trout")
。因此,所有的狗和猫都是动物,所有的鲑鱼和鳟鱼都是鱼。这两个变量远远比其他六个变量重要。因此,如果我运行三个森林,一个使用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 OOBError2.OOB 2 0.17732883.OOB 3 0.17283954.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 OOBError2.OOB 2 0.18069583.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 OOBError2.OOB 2 0.16610553.OOB 3 0.17508424.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 OOBError2.OOB 2 0.18742993.OOB 3 0.17396184.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
相关的任何一般性评论)都将不胜感激。对于任何偶然发现此内容并寻找tuneRF
帮助的人,我还发现这篇文章很有帮助。R: tuneRF函数(randomForest包)的不明确行为
值得一提的是,对于较小的特征集(具有非包含性特征),最优的mtry似乎是3,而对于较大的特征集,最优的mtry仅为2,这初看起来有些违反直觉,但当你考虑到A和B的包含性时,这确实/可能是有意义的。
回答:
-
在这种情况下(以及其他情况),选择哪个mtry对性能没有太大影响。只有当你想赢得winner-takes-all的kaggle比赛时,你可能会将许多其他学习算法混合成一个巨大的集成。在实践中,你几乎会得到相同的预测结果。
-
当你测试的参数组合很少时,你不需要逐步优化。只要尝试所有组合,并多次重复以找出哪个mtry稍微更好。
-
每次我使用tuneRF时,我都感到失望。每次我最终都编写自己的逐步优化程序,或者简单地多次尝试所有组合。
-
mtry与oob-err之间的关系不一定是具有单一最小值的平滑曲线,尽管应该观察到一般趋势。很难判断一个最小值是由于噪声还是一般趋势造成的。