随机森林 bootstrap 训练和森林生成
Random forest bootstrap training and forest generation
我有大量的随机森林训练数据 (dim: 47600811*9)。我想取多个(假设 1000 个)维度为 10000*9 的自举样本(在每个 运行 中取 9000 个负 class 和 1000 个正 class 数据点)并迭代生成所有树它们,然后将所有这些树组合成 1 个森林。
下面给出了所需代码的粗略概念。有人可以指导我如何从我的实际 trainData 中替换生成随机样本并以迭代方式为它们优化生成树吗?这将是很大的帮助。谢谢
library(doSNOW)
library(randomForest)
cl <- makeCluster(8)
registerDoSNOW(cl)
for (i=1:1000){
B <- 1000
U <- 9000
dataB <- trainData[sample(which(trainData$class == "B"), B,replace=TRUE),]
dataU <- trainData[sample(which(trainData$class == "U"), U,replace=TRUE),]
subset <- rbind(dataB, dataU)
我不确定这是否是从实际 trainData 一次又一次(1000 次)生成子集的最佳方式。
rf <- foreach(ntree=rep(125, 8), .packages='randomForest') %dopar% {
randomForest(subset[,-1], subset$class, ntree=ntree)
}
}
crf <- do.call('combine', rf)
print(crf)
stopCluster(cl)
像这样的东西会起作用
# Replicate expression 1000 times, store output of each replication in a list
# Find indices of class B and sample 9000 times with replacement
# Do the same 1000 times for class U. Combine the two vectors of indices
i = replicate(1000, {c(sample(which(trainData$class == "B"), 9000, replace = T), sample(which(trainData$class == "U"), 1000, replace = T))})
然后将i
输入lapply
的并行版本
mclapply(i, function(i, ntree) randomForest(trainData[i,-1], trainData[i,]$class, ntree=ntree)
尽管您的示例并行化了内部循环而不是外部循环,但只要内部 foreach 循环的执行时间超过几秒,它就可以正常工作,这几乎可以肯定。但是,您的程序确实有一个错误:它会丢弃前 999 个 foreach 结果,而只处理最后一个结果。要解决此问题,您可以预先分配一个长度为 1000*8 的列表,并在外部 for 循环的每次迭代中将 foreach 的结果分配给它。例如:
library(doSNOW)
library(randomForest)
trainData <- data.frame(a=rnorm(20), b=rnorm(20),
class=c(rep("U", 10), rep("B", 10)))
n <- 1000 # outer loop count
chunksize <- 125 # value of ntree used in inner loop
nw <- 8 # number of cluster workers
cl <- makeCluster(nw)
registerDoSNOW(cl)
rf <- vector('list', n * nw)
for (i in 1:n) {
B <- 1000
U <- 9000
dataB <- trainData[sample(which(trainData$class == "B"), B,replace=TRUE),]
dataU <- trainData[sample(which(trainData$class == "U"), U,replace=TRUE),]
subset <- rbind(dataB, dataU)
ix <- seq((i-1) * nw + 1, i * nw)
rf[ix] <- foreach(ntree=rep(chunksize, nw),
.packages='randomForest') %dopar% {
randomForest(subset[,-1], subset$class, ntree=ntree)
}
}
cat(sprintf("# models: %d; expected # models: %d\n", length(rf), n * nw))
cat(sprintf("expected total # trees: %d\n", n * nw * chunksize))
crf <- do.call('combine', rf)
print(crf)
这应该可以解决您在给我的评论中提到的问题。
我有大量的随机森林训练数据 (dim: 47600811*9)。我想取多个(假设 1000 个)维度为 10000*9 的自举样本(在每个 运行 中取 9000 个负 class 和 1000 个正 class 数据点)并迭代生成所有树它们,然后将所有这些树组合成 1 个森林。 下面给出了所需代码的粗略概念。有人可以指导我如何从我的实际 trainData 中替换生成随机样本并以迭代方式为它们优化生成树吗?这将是很大的帮助。谢谢
library(doSNOW)
library(randomForest)
cl <- makeCluster(8)
registerDoSNOW(cl)
for (i=1:1000){
B <- 1000
U <- 9000
dataB <- trainData[sample(which(trainData$class == "B"), B,replace=TRUE),]
dataU <- trainData[sample(which(trainData$class == "U"), U,replace=TRUE),]
subset <- rbind(dataB, dataU)
我不确定这是否是从实际 trainData 一次又一次(1000 次)生成子集的最佳方式。
rf <- foreach(ntree=rep(125, 8), .packages='randomForest') %dopar% {
randomForest(subset[,-1], subset$class, ntree=ntree)
}
}
crf <- do.call('combine', rf)
print(crf)
stopCluster(cl)
像这样的东西会起作用
# Replicate expression 1000 times, store output of each replication in a list
# Find indices of class B and sample 9000 times with replacement
# Do the same 1000 times for class U. Combine the two vectors of indices
i = replicate(1000, {c(sample(which(trainData$class == "B"), 9000, replace = T), sample(which(trainData$class == "U"), 1000, replace = T))})
然后将i
输入lapply
mclapply(i, function(i, ntree) randomForest(trainData[i,-1], trainData[i,]$class, ntree=ntree)
尽管您的示例并行化了内部循环而不是外部循环,但只要内部 foreach 循环的执行时间超过几秒,它就可以正常工作,这几乎可以肯定。但是,您的程序确实有一个错误:它会丢弃前 999 个 foreach 结果,而只处理最后一个结果。要解决此问题,您可以预先分配一个长度为 1000*8 的列表,并在外部 for 循环的每次迭代中将 foreach 的结果分配给它。例如:
library(doSNOW)
library(randomForest)
trainData <- data.frame(a=rnorm(20), b=rnorm(20),
class=c(rep("U", 10), rep("B", 10)))
n <- 1000 # outer loop count
chunksize <- 125 # value of ntree used in inner loop
nw <- 8 # number of cluster workers
cl <- makeCluster(nw)
registerDoSNOW(cl)
rf <- vector('list', n * nw)
for (i in 1:n) {
B <- 1000
U <- 9000
dataB <- trainData[sample(which(trainData$class == "B"), B,replace=TRUE),]
dataU <- trainData[sample(which(trainData$class == "U"), U,replace=TRUE),]
subset <- rbind(dataB, dataU)
ix <- seq((i-1) * nw + 1, i * nw)
rf[ix] <- foreach(ntree=rep(chunksize, nw),
.packages='randomForest') %dopar% {
randomForest(subset[,-1], subset$class, ntree=ntree)
}
}
cat(sprintf("# models: %d; expected # models: %d\n", length(rf), n * nw))
cat(sprintf("expected total # trees: %d\n", n * nw * chunksize))
crf <- do.call('combine', rf)
print(crf)
这应该可以解决您在给我的评论中提到的问题。