4

で SVM パラメータを調整すると、非常に奇妙な動作が見られましたcaret。チューニングを行わずに 1 つのモデルをトレーニングする場合、放射基底カーネルを使用する SVM は、線形カーネルを使用する SVM よりも時間がかかりますが、これは予想されることです。ただし、同じペナルティ グリッド上で両方のカーネルを使用して SVM を調整する場合、線形カーネルを使用した SVM は、放射基底カーネルを使用した SVM よりも大幅に時間がかかります。caretこの動作は、R 3.2 および6.0-47を使用する Windows と Linux の両方で簡単に再現できます。線形 SVM の調整が放射基底カーネル SVM よりもはるかに時間がかかる理由を知っている人はいますか?

SVM linear
   user  system elapsed 
   0.51    0.00    0.52 

SVM radial
   user  system elapsed 
   0.85    0.00    0.84 

SVM linear tuning
   user  system elapsed 
 129.98    0.02  130.08 

SVM radial tuning
   user  system elapsed 
   2.44    0.05    2.48 

おもちゃのサンプル コードは次のとおりです。

library(data.table)
library(kernlab)
library(caret)

n <- 1000
p <- 10

dat <- data.table(y = as.factor(sample(c('p', 'n'), n, replace = T)))
dat[, (paste0('x', 1:p)) := lapply(1:p, function(x) rnorm(n, 0, 1))]
dat <- as.data.frame(dat)

sigmas <- sigest(as.matrix(dat[, -1]), na.action = na.omit, scaled = TRUE)
sigma  <- mean(as.vector(sigmas[-2]))

cat('\nSVM linear\n')
print(system.time(fit1 <- train(y ~ ., data = dat, method = 'svmLinear', tuneLength = 1,
                                 trControl = trainControl(method = 'cv', number = 3))))

cat('\nSVM radial\n')
print(system.time(fit2 <- train(y ~ ., data = dat, method = 'svmRadial', tuneLength = 1,
                                 trControl = trainControl(method = 'cv', number = 3))))

cat('\nSVM linear tuning\n')
print(system.time(fit3 <- train(y ~ ., data = dat, method = 'svmLinear',
                                 tuneGrid = expand.grid(C = 2 ^ seq(-5, 15, 5)),
                                 trControl = trainControl(method = 'cv', number = 3))))

cat('\nSVM radial tuning\n')
print(system.time(fit4 <- train(y ~ ., data = dat, method = 'svmRadial',
                                 tuneGrid = expand.grid(C = 2 ^ seq(-5, 15, 5), sigma = sigma),
                                 trControl = trainControl(method = 'cv', number = 3))))
4

2 に答える 2

3

見てみると、問題は にあるとは思いませんがcaret、 の舞台裏で(背後で)何が起こっているのかに問題があると思いますkernlab
スタック オーバーフローSVM自体で他の場所で述べたように、集中的なアルゴリズムです。の時間計算量SVMは O(n*n) です。SVM現在、これは呼び出し間の違いを考慮していません。しかし、何が起こっているように見えるかは、非常に深いスタックを介してコンパイルされた C コードを呼び出した後です (コンパイルされた C コードへのSVM > .Local > .call.呼び出し.callであり、私のナレッジ ベースから)。ほとんどの場合、予想外の遅い時間が からRに移動するのを目にします。Cそれは物事がどのように渡されるかによるものです。マトリックスを引っ張っているので、これはネーミングまたはディメンションの問題の想定にさらに役立ち、反対側で余分な作業が発生します。
このコードのプロファイリング方法を見ると、ボトルネックがかなり明確になります。

フォント サイズについての謝罪 - 深い積み重ねであり、個々の機能よりも全体的な形状が物語を語っていると思います。Ctrl + 以下をスパムしてください。

nSVM_linear健全なプロファイルと多くのフレンドリーな R 関数のように見えます。

nSVM_linear

同じ取引nSVM radial

ここに画像の説明を入力

ここで「ラジアル チューニング」を開始すると、try-callスタックが歪み始め、よりフラットな構造が見え始めますが、すべてが迅速に実行されているように見えます。

ここに画像の説明を入力

うわあ。C場合によっては 100 秒以上かかる線形チューニング呼び出しの完全に異なる構造。

ここに画像の説明を入力

そうは言っても、ボトルネックはCからコンパイルされたコードにあるようkernlabです。パッケージはlibsvm非常に効率的に接続しているため、呼び出されているコードに実際の問題があるとは想像できません。どのように (安全ベースの機能または R からの入力の問題)、ある場所から別の場所に移動するときに問題が発生するのかを実際に特定することは、私よりも優れた人の仕事です。

于 2015-05-22T03:23:51.630 に答える
0

svmRadialLinuxでのパフォーマンスが非常に悪いことに遭遇しました。問題は multicore の使用にあったことがわかりDoMCました。svmRadialシングルコアで問題なく動きます。関数は、私が見たこの動作を示すkernlab唯一のものです。他の人が言及したものに加えて、caret追加するもう1つの問題。kernlab

于 2016-06-19T11:20:02.907 に答える