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 に答える