Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从party:::ctree模型中删除培训数据?_R_Memory Management_Classification_Decision Tree - Fatal编程技术网

如何从party:::ctree模型中删除培训数据?

如何从party:::ctree模型中删除培训数据?,r,memory-management,classification,decision-tree,R,Memory Management,Classification,Decision Tree,我创建了几个ctree模型(大约40到80个),我想经常对它们进行评估 一个问题是模型对象非常大(40个模型需要超过2.8G的内存),在我看来,它们存储了训练数据,可能是modelname@data及modelname@responses,而不仅仅是与预测新数据相关的信息 大多数其他R学习包都有可配置的选项,可以选择是否将数据包含在模型对象中,但我在文档中找不到任何提示。我还尝试通过指定空的ModelEnv对象 modelname@data <- new("ModelEnv") 事实证明

我创建了几个ctree模型(大约40到80个),我想经常对它们进行评估

一个问题是模型对象非常大(40个模型需要超过2.8G的内存),在我看来,它们存储了训练数据,可能是modelname@data及modelname@responses,而不仅仅是与预测新数据相关的信息

大多数其他R学习包都有可配置的选项,可以选择是否将数据包含在模型对象中,但我在文档中找不到任何提示。我还尝试通过指定空的ModelEnv对象

modelname@data <- new("ModelEnv")
事实证明,party包中有一个C函数用于删除这些权重,称为
R\u remove\u weights
,定义如下:

SEXP R_remove_weights(SEXP subtree, SEXP removestats) {
    C_remove_weights(subtree, LOGICAL(removestats)[0]);
    return(R_NilValue);
}
它也可以很好地工作:

# cc is my model object

sum(unlist(lapply(slotNames(cc), function (x)  object.size(slot(cc, x)))))
# returns: [1] 2521256
save(cc, file="cc_before.RData")

.Call("R_remove_weights", cc@tree, TRUE, PACKAGE="party")
# returns NULL and removes weights and node statistics

sum(unlist(lapply(slotNames(cc), function (x)  object.size(slot(cc, x)))))
# returns: [1] 1521392
save(cc, file="cc_after.RData")
如您所见,它大大减小了对象大小,从大约2.5MB减小到1.5MB

但奇怪的是,相应的RData文件非常庞大,对它们没有影响:

$ ls -lh cc*
-rw-r--r-- 1 user user 9.6M Aug 24 15:44 cc_after.RData
-rw-r--r-- 1 user user 9.6M Aug 24 15:43 cc_before.RData
解压缩文件时,2.5MB对象将占用近100MB的空间:

$ cp cc_before.RData cc_before.gz
$ gunzip cc_before.gz 
$ ls -lh cc_before*
-rw-r--r-- 1 user user  98M Aug 24 15:45 cc_before

有什么想法吗?是什么原因造成的?

您正在寻找的是删除插槽。警告:考虑到
参与方
函数如何处理对象,这可能相当危险

尽管如此,请看一下
slotNames(您的型号)
。您还可以尝试
object.size(slot(yourModel),slotNameOfInterest)
来检查不同插槽的大小。您可以轻松创建一个排序表,以确保每个插槽中对象的大小


在任何情况下,
data
的槽都是一个
ModelEnvFormula
(我称之为“MEF”)对象。你可以创建一个虚拟的MEF:
dummyMEF我找到了解决这个问题的方法,所以如果有人遇到同样的问题,我会写下这个答案。我会描述我的过程,所以可能有点杂乱无章,请耐心听我说

在没有任何线索的情况下,我考虑过用核弹炸槽和移除重物,以使物体尽可能小,至少节省一些内存,以防找不到修复方法。因此,我首先删除了
@data
@responses
,如果没有它们,预测仍然正常,但对.RData文件大小没有影响

我反过来创建了一个空的ctree模型,只是将树插入其中:

> library(party)

## create reference predictions for the dataset
> predictions.org <- treeresponse(c1, d)

## save tree object for reference
save(c1, "testSize_c1.RData")
现在,让我们创建一个空CTree并仅复制树:

## extract the tree only 
> c1Tree <- c1@tree

## create empty tree and plug in the extracted one 
> newCTree <- new("BinaryTree")
> newCTree@tree <- c1Tree

## save tree for reference 
save(newCTree, file="testSize_newCTree.RData")
但是,它不能用于预测:

## predict with the new tree
> predictions.new <- treeresponse(newCTree, d)
Error in object@cond_distr_response(newdata = newdata, ...) : 
  unused argument(s) (newdata = newdata)
这非常有效,但现在RData文件的大小恢复到其原始值:

$ ls -lh testSize_newCTree_with_cdr.RData 
-rw-r--r-- 1 user user 9.6M 2011-08-25 14:37 testSize_newCTree_with_cdr.RData
只需打印插槽,即可将其显示为绑定到环境的函数:

> c1@cond_distr_response
function (newdata = NULL, mincriterion = 0, ...) 
{
    wh <- RET@get_where(newdata = newdata, mincriterion = mincriterion)
    response <- object@responses
    if (any(response@is_censored)) {
        swh <- sort(unique(wh))
        RET <- vector(mode = "list", length = length(wh))
        resp <- response@variables[[1]]
        for (i in 1:length(swh)) {
            w <- weights * (where == swh[i])
            RET[wh == swh[i]] <- list(mysurvfit(resp, weights = w))
        }
        return(RET)
    }
    RET <- .Call("R_getpredictions", tree, wh, PACKAGE = "party")
    return(RET)
}
<environment: 0x44e8090>
现在,我们只需保存提取的树和公式字符串即可预测新数据:

> save(c1Tree, org.formula, file="testSize_extractedObjects.RData")
我们可以进一步删除上述更新问题中所述的不必要权重:

> .Call("R_remove_weights", c1Tree, TRUE, PACKAGE="party")
> save(c1Tree, org.formula, file="testSize_extractedObjects__removedWeights.RData")
现在让我们再次看看文件大小:

$ ls -lh testSize_extractedObjects*
-rw-r--r-- 1 user user 109K 2011-08-25 15:31 testSize_extractedObjects.RData
-rw-r--r-- 1 user user  43K 2011-08-25 15:31 testSize_extractedObjects__removedWeights.RData

最后,使用该模型只需要43K,而不是(压缩)9.6M。我现在应该能够在我的3G堆空间中容纳我想要的任何数量。万岁

如果您可以将
dput
的结果发布到一个小样本对象上,这会有所帮助。如果您使用
str
可以查看对象中是否存储了培训数据。注意:我重新标记了问题并删除了“party”标签,因为它没有很好的定义,因此肯定不限于R包。我添加了内存管理,因为这似乎是主要的动机。
> c1@cond_distr_response
function (newdata = NULL, mincriterion = 0, ...) 
{
    wh <- RET@get_where(newdata = newdata, mincriterion = mincriterion)
    response <- object@responses
    if (any(response@is_censored)) {
        swh <- sort(unique(wh))
        RET <- vector(mode = "list", length = length(wh))
        resp <- response@variables[[1]]
        for (i in 1:length(swh)) {
            w <- weights * (where == swh[i])
            RET[wh == swh[i]] <- list(mysurvfit(resp, weights = w))
        }
        return(RET)
    }
    RET <- .Call("R_getpredictions", tree, wh, PACKAGE = "party")
    return(RET)
}
<environment: 0x44e8090>
## create a character string of the formula which was used to fit the free
## (there might be a more neat way to do this)
> library(stringr)
> org.formula <- str_c(
                   do.call(str_c, as.list(deparse(c1@data@formula$response[[2]]))),
                   "~", 
                   do.call(str_c, as.list(deparse(c1@data@formula$input[[2]]))))

## call the internal ctree preprocessing 
> data.dpp <- party:::ctreedpp(as.formula(org.formula), d)

## create the data object necessary for the ctree C code
> data.ivf <- party:::initVariableFrame.df(data.dpp@menv@get("input"), 
                                           trafo = ptrafo)

## now call the tree traversal routine, note that it only requires the tree
## extracted from the @tree slot, not the whole object
> nodeID <- .Call("R_get_nodeID", c1Tree, data.ivf, 0, PACKAGE = "party")

## now determine the respective responses
> predictions.syn <- .Call("R_getpredictions", c1Tree, nodeID, PACKAGE = "party")

## check correctness
> identical(predictions.org, predictions.syn)
[1] TRUE
> save(c1Tree, org.formula, file="testSize_extractedObjects.RData")
> .Call("R_remove_weights", c1Tree, TRUE, PACKAGE="party")
> save(c1Tree, org.formula, file="testSize_extractedObjects__removedWeights.RData")
$ ls -lh testSize_extractedObjects*
-rw-r--r-- 1 user user 109K 2011-08-25 15:31 testSize_extractedObjects.RData
-rw-r--r-- 1 user user  43K 2011-08-25 15:31 testSize_extractedObjects__removedWeights.RData