5

我观察到,仅对于 rpart 包(用于决策树模型),当我增加数据中因子级别的数量时,包的速度会急剧下降。我和其他包比较过,而且只针对rpart,好像是这样。下面是在我的数据上尝试各种算法的图表。X 轴显示使用的因子水平数,Y 轴显示时间(以秒为单位)。如您所见,对于 rpart,因子数量增加的峰值是巨大的。在此处输入图像描述

通过在线阅读一些资源和堆栈溢出的页面,我了解到这与 rpart:::rpart.matrix 中的 for 循环有关,使用 [ls]apply 更改它会加快这部分代码的速度。

这是原始代码

function (frame)
{
    if (!inherits(frame, "data.frame") || is.null(attr(frame,
        "terms")))
        return(as.matrix(frame))
    for (i in 1:ncol(frame)) {
        if (is.character(frame[[i]]))
            frame[[i]] <- as.numeric(factor(frame[[i]]))
        else if (!is.numeric(frame[[i]]))
            frame[[i]] <- as.numeric(frame[[i]])
    }
    X <- model.matrix(attr(frame, "terms"), frame)[, -1L, drop = FALSE]
    colnames(X) <- sub("^`(.*)`", "\\1", colnames(X))
    class(X) <- c("rpart.matrix", class(X))
    X
}

这是建议加快循环的更改

# exactly the same as rpart.matrix, but with for replaced by lapply
f <- function(frame)
{
    if (!inherits(frame, "data.frame") || is.null(attr(frame, 
        "terms"))) 
        return(as.matrix(frame))
    frame[] <- lapply(frame, function(x) {
        if (is.character(x))
            as.numeric(factor(x))
        else if(!is.numeric(x))
            as.numeric(x)
        else x
    })
    X <- model.matrix(attr(frame, "terms"), frame)[, -1L, drop = FALSE]
    colnames(X) <- sub("^`(.*)`", "\\1", colnames(X))
    class(X) <- c("rpart.matrix", class(X))
    X
}

但是,如何让整个 rpart 包加速?

是否可以下载 rpart 代码并进行这些更改?

另外,我知道速度变慢的原因是将分类变量转换为 0/1 类型的“扁平化变量”的代码。这真的有必要吗?在内部实现中是否可以通过为每个因素维护一个列表来区别对待分类变量,以标记使用该因素的行?

请指教。谢谢。

4

1 回答 1

0

您可以使用 trace 更改 rpart.matrix 中的功能代码

trace("rpart.matrix", where=asNamespace("rpart"), edit=TRUE)
于 2021-07-30T17:39:05.673 回答