我在R中使用randomForest包来构建几个物种分布模型。我的反应变量是二元(0 - 缺席或1 - 存在),并且非常不平衡 - 对于某些物种,缺席的比例:存在是37:1。这种不平衡(或零膨胀)导致可疑的袋外误差估计 - 缺勤与存在的比率越大,我的袋外(OOB)误差估计越低。
为了弥补这种不平衡,我想实施分层抽样,使得随机森林中的每棵树都包含来自存在和缺席类别的相同(或至少不太平衡)的结果。我很惊讶,分层和非分层模型OOB误差估计似乎没有任何差别。请参阅下面的代码:
> set.seed(25)
> HHrf<- randomForest(formula = factor(HH_Pres) ~ SST + Dist2Shr+ DaylightHours + Bathy + Slope + MoonPhase + factor(Region) + Chla , data = bll_HH, ntree = 500, replace = FALSE, importance = TRUE, na.action = na.omit)
> HHrf
Call:
randomForest(formula = factor(HH_Pres) ~ SST + Dist2Shr + DaylightHours + Bathy + Slope + MoonPhase + factor(Region) + Chla, data = bll_HH, ntree = 500, replace = FALSE, importance = TRUE, na.action = na.omit)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 2
OOB estimate of error rate: 19.1%
Confusion matrix:
0 1 class.error
0 422 18 0.04090909
1 84 10 0.89361702
> HHrf_strata<- randomForest(formula = factor(HH_Pres) ~ SST + Chla + Dist2Shr+ DaylightHours + Bathy + Slope + MoonPhase + factor(Region), data = bll_HH, ntree = 500, replace = FALSE, importance = TRUE, strata = bll_HH$HH_Pres, sampsize = ceiling(.632*nrow(bll_HH)))
> HHrf
Call:
randomForest(formula = factor(HH_Pres) ~ SST + Dist2Shr + DaylightHours + Bathy + Slope + MoonPhase + factor(Region) + Chla, data = bll_HH, ntree = 500, replace = FALSE, importance = TRUE, na.action = na.omit)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 2
OOB estimate of error rate: 19.1%
Confusion matrix:
0 1 class.error
0 422 18 0.04090909
1 84 10 0.89361702
我是否有理由在两种情况下获得相同的结果?对于strata参数,我指定了我的响应变量HH_Pres。对于sampsize参数,我指定它应该只是整个数据集的63.2%。
任何人都知道我做错了什么?或者这是预期的吗?
谢谢,
莉莎
重现此问题:
示例数据:https://docs.google.com/file/d/0B-JMocik79JzY3B4U3NoU3kyNW8/edit
代码:
bll = read.csv("bll_Nov2013_NMV.csv", header=TRUE)
HH_Pres <- bll$HammerHeadALL_Presence
Slope <-bll$Slope
Dist2Shr <-bll$Dist2Shr
Bathy <-bll$Bathy2
Chla <-bll$GSM_Chl_Daily_MF
SST <-bll$SST_PF_daily
Region <- bll$Region
MoonPhase <-bll$MoonPhase
DaylightHours <- bll$DaylightHours
bll_HH <- data.frame(HH_Pres, Slope, Dist2Shr, Bathy, Chla, SST, DaylightHours, MoonPhase, Region)
set.seed(25)
HHrf<- randomForest(formula = factor(HH_Pres) ~ SST + Dist2Shr+ DaylightHours + Bathy + Slope + MoonPhase + factor(Region) + Chla , data = bll_HH, ntree = 500, replace = FALSE, importance = TRUE, na.action = na.omit)
HHrf
set.seed(25)
HHrf_strata<- randomForest(formula = factor(HH_Pres) ~ SST + Chla + Dist2Shr+ DaylightHours + Bathy + Slope + MoonPhase + factor(Region), data = bll_HH, strata = bll_HH$HH_Pres, sampsize = c(100, 50), ntree = 500, replace = FALSE, importance = TRUE)
HHrf
答案 0 :(得分:5)
据我所知,sampsize
参数应该是一个与数据集中类的数量相同的向量。如果在strata
参数中指定因子变量,则sampsize
应该被赋予一个与strata
参数中的因子数长度相同的向量。我不确定它是否像你在你的问题中描述的那样表现,但是因为我使用了randomForest
函数已经有一段时间了。
从帮助文件中,它说:
strata
用于分层抽样的(因子)变量。
sampsize
:要抽取的样本的大小。对于分类,如果sampsize是矢量 在分层数量的长度,然后采样分层 strata和sampsize的元素表示要绘制的数字 来自阶层。
例如,由于您的分类有2个不同的类,因此您需要给sampsize
一个长度为2的向量,该向量指定您希望在训练期间从每个类中采样的观察数量。
e.g。 sampsize=c(100,50)
此外,您可以指定要清楚的组名称。
e.g。 sampsize=c('0'=100, '1'=50)
使用sampsize
参数的帮助文件中的示例,以澄清:
## stratified sampling: draw 20, 30, and 20 of the species to grow each tree.
data(iris)
(iris.rf2 <- randomForest(iris[1:4], iris$Species, sampsize=c(20, 30, 20)))
编辑:在strata
中添加了关于randomForest
参数的一些注释。
编辑:确保给strata
参数一个因子变量!
e.g。试试strata = factor(HH_Pres), sampsize = c(...)
其中c(...)
是一个与length(levels(factor(bll_HH$HH_Pres)))
编辑:
好的,我尝试使用您的数据运行代码,它适用于我。
# Fix up the data set to have HH_Pres and Region as factors
bll_HH$Region <- factor(bll_HH$Region)
bll_HH$HH_Pres <- factor(bll_HH$HH_Pres)
# Original RF code
set.seed(25)
HHrf <- randomForest(formula=HH_Pres ~ SST + Dist2Shr + DaylightHours + Bathy +
Slope + MoonPhase + Chla + Region,
data=bll_HH, ntree = 500, replace = FALSE,
importance = TRUE, na.action = na.omit)
HHrf
# Output
# OOB estimate of error rate: 18.91%
# Confusion matrix:
# 0 1 class.error
# 0 425 15 0.03409091
# 1 86 8 0.91489362
# Take 63.2% from each class
mySampSize <- ceiling(table(bll_HH$HH_Pres) * 0.632)
set.seed(25)
HHrf <- randomForest(formula=HH_Pres ~ SST + Dist2Shr + DaylightHours + Bathy +
Slope + MoonPhase + Chla + Region,
data=bll_HH, ntree = 500, replace = FALSE,
importance = TRUE, na.action = na.omit,
sampsize=mySampSize)
HHrf
# Output
# OOB estimate of error rate: 18.91%
# Confusion matrix:
# 0 1 class.error
# 0 424 16 0.03636364
# 1 85 9 0.90425532
请注意,在这种情况下,OOB误差估计是相同的,即使我们仅使用我们的bootstrap样本中每个类的63.2%的数据。这可能是由于使用了与训练数据中的类别分布成比例的样本大小,以及数据集的相对较小的大小。让我们尝试更改mySampSize
以确保它真的有效。
# Change mySampSize. Sample 100 from class 0 and 50 from class 1
mySampSize[1] <- 100
mySampSize[2] <- 50
set.seed(25)
HHrf <- randomForest(formula=HH_Pres ~ SST + Dist2Shr + DaylightHours + Bathy +
Slope + MoonPhase + Chla + Region,
data=bll_HH, ntree = 500, replace = FALSE,
importance = TRUE, na.action = na.omit,
sampsize=mySampSize)
HHrf
# Output
# OOB estimate of error rate: 21.16%
# Confusion matrix:
# 0 1 class.error
# 0 382 58 0.1318182
# 1 55 39 0.5851064
答案 1 :(得分:0)
这种语法似乎对我的数据工作正常。 OOB为32.21%,类错误:0.32,0.29。我确实将Bootstraps的数量增加到1000.我总是建议使用索引来定义RF模型。在某些情况下,符号语法似乎不稳定。
require(randomForest)
HHrf <- read.csv("bll_HH.csv")
set.seed(25)
( rf.mdl <- randomForest( y=as.factor(HHrf[,"HH_Pres"]), x=HHrf[,2:ncol(HHrf)],
strata=as.factor(HHrf[,"HH_Pres"]), sampsize=c(50,50),
ntree=1000) )
答案 2 :(得分:0)
我也遇到了这个问题。我注意到我在使用 importance = TRUE
时的错误率发生了显着变化。这和我没有选择带抽样分层是不一样的。
对我来说,它最终成为我的分类树没有重要性/准确性分数的权衡。这似乎是此实现中的众多错误之一。