我是 R 的新手(第 2 天),我的任务是构建一个随机森林森林。每个单独的随机森林将使用不同的训练集构建,最后我们将结合所有森林进行预测。我正在 R 中实现这个,并且在组合两个不是使用相同集合构建的森林时遇到了一些困难。我的尝试如下:
d1 = read.csv("../data/rr/train/10/chunk0.csv",header=TRUE)
d2 = read.csv("../data/rr/train/10/chunk1.csv",header=TRUE)
rf1 = randomForest(A55~., data=d1, ntree=10)
rf2 = randomForest(A55~., data=d2, ntree=10)
rf = combine(rf1,rf2)
这当然会产生错误:
Error in rf$votes + ifelse(is.na(rflist[[i]]$votes), 0, rflist[[i]]$votes) :
non-conformable arrays
In addition: Warning message:
In rf$oob.times + rflist[[i]]$oob.times :
longer object length is not a multiple of shorter object length
我已经浏览了一段时间的网络,寻找有关此的线索,但尚未取得任何成功。这里的任何帮助将不胜感激。
最佳答案
啊。这要么是 combine
中的疏忽,要么是您尝试做的事情是荒谬的,这取决于您的观点。
投票矩阵记录了每个响应类别的训练数据中每个案例在森林中的投票数。自然,它的行数将与训练数据中的行数相同。combine
假设您在同一组数据上运行了两次随机森林,因此这些矩阵的维度将相同。这样做是因为它想为您提供组合林的一些“整体”误差估计。
但是如果两个数据集不同,那么结合投票矩阵就变得毫无意义了。您可以通过简单地从较大的训练数据集中删除一行来运行 combine
,但组合森林中的结果投票矩阵将是胡言乱语,因为每一行都是两个不同训练案例的投票组合。
所以也许这只是一个可以在 combine
中关闭的选项。因为在结果对象上结合实际树和 predict
仍然有意义。但是 combine
输出中的一些“组合”错误估计将毫无意义。
长话短说,让每个训练数据集的大小相同,它就会运行。但是,如果您这样做,除了进行新的预测之外,我不会将结果对象用于任何其他目的。任何总结森林表现的组合都是无稽之谈。
但是,我认为使用 combine
的预期方法是在完整数据集上拟合多个随机森林,但减少树木数量,然后组合这些森林。
编辑
我继续修改 combine
以“处理”不相等的训练集大小。这意味着我删除了一大块代码,这些代码试图将不匹配的东西拼接在一起。但我保留了结合森林的部分,所以你仍然可以使用 predict
:
my_combine <- function (...)
{
pad0 <- function(x, len) c(x, rep(0, len - length(x)))
padm0 <- function(x, len) rbind(x, matrix(0, nrow = len -
nrow(x), ncol = ncol(x)))
rflist <- list(...)
areForest <- sapply(rflist, function(x) inherits(x, "randomForest"))
if (any(!areForest))
stop("Argument must be a list of randomForest objects")
rf <- rflist[[1]]
classRF <- rf$type == "classification"
trees <- sapply(rflist, function(x) x$ntree)
ntree <- sum(trees)
rf$ntree <- ntree
nforest <- length(rflist)
haveTest <- !any(sapply(rflist, function(x) is.null(x$test)))
vlist <- lapply(rflist, function(x) rownames(importance(x)))
numvars <- sapply(vlist, length)
if (!all(numvars[1] == numvars[-1]))
stop("Unequal number of predictor variables in the randomForest objects.")
for (i in seq_along(vlist)) {
if (!all(vlist[[i]] == vlist[[1]]))
stop("Predictor variables are different in the randomForest objects.")
}
haveForest <- sapply(rflist, function(x) !is.null(x$forest))
if (all(haveForest)) {
nrnodes <- max(sapply(rflist, function(x) x$forest$nrnodes))
rf$forest$nrnodes <- nrnodes
rf$forest$ndbigtree <- unlist(sapply(rflist, function(x) x$forest$ndbigtree))
rf$forest$nodestatus <- do.call("cbind", lapply(rflist,
function(x) padm0(x$forest$nodestatus, nrnodes)))
rf$forest$bestvar <- do.call("cbind", lapply(rflist,
function(x) padm0(x$forest$bestvar, nrnodes)))
rf$forest$xbestsplit <- do.call("cbind", lapply(rflist,
function(x) padm0(x$forest$xbestsplit, nrnodes)))
rf$forest$nodepred <- do.call("cbind", lapply(rflist,
function(x) padm0(x$forest$nodepred, nrnodes)))
tree.dim <- dim(rf$forest$treemap)
if (classRF) {
rf$forest$treemap <- array(unlist(lapply(rflist,
function(x) apply(x$forest$treemap, 2:3, pad0,
nrnodes))), c(nrnodes, 2, ntree))
}
else {
rf$forest$leftDaughter <- do.call("cbind", lapply(rflist,
function(x) padm0(x$forest$leftDaughter, nrnodes)))
rf$forest$rightDaughter <- do.call("cbind", lapply(rflist,
function(x) padm0(x$forest$rightDaughter, nrnodes)))
}
rf$forest$ntree <- ntree
if (classRF)
rf$forest$cutoff <- rflist[[1]]$forest$cutoff
}
else {
rf$forest <- NULL
}
#
#Tons of stuff removed here...
#
if (classRF) {
rf$confusion <- NULL
rf$err.rate <- NULL
if (haveTest) {
rf$test$confusion <- NULL
rf$err.rate <- NULL
}
}
else {
rf$mse <- rf$rsq <- NULL
if (haveTest)
rf$test$mse <- rf$test$rsq <- NULL
}
rf
}
然后你可以像这样测试它:
data(iris)
d <- iris[sample(150,150),]
d1 <- d[1:70,]
d2 <- d[71:150,]
rf1 <- randomForest(Species ~ ., d1, ntree=50, norm.votes=FALSE)
rf2 <- randomForest(Species ~ ., d2, ntree=50, norm.votes=FALSE)
rf.all <- my_combine(rf1,rf2)
predict(rf.all,newdata = iris)
显然,这绝对没有保修! :)
关于r - 在 R 中结合使用不同训练集构建的随机森林,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19170130/