在R中使用不同训练集构建的随机森林组合

我是R的新手(使用第二天),被分配了构建一个随机森林集合的任务。每个单独的随机森林将使用不同的训练集构建,我们将在最后将所有森林组合起来进行预测。我正在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 arraysIn 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)

显然,这完全没有保修!:)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注