2012-01-06 4 views
2

簡体例(機能rbfkernlabパッケージからである)でkernlabパッケージからrbfdotを使用してパフォーマンス:私はouter()を試してみた悪いスピードアップする必要があります私のゆっくりと動作するコードのループ

install.packages('kernlab')  
library('kernlab') 

rbf <- rbfdot(sigma=1) 

test <- matrix(NaN,nrow=5,ncol=10) 
for (i in 1:5) { 
       for (j in 1:10) { test[i,j] <- rbf(i,j)} 
       } 

それrbf関数が必要な長さ(50)を返さないために機能しません。膨大な量のデータがあるので、このコードを高速化する必要があります。私はこれをスピードアップするためにベクトル化が聖杯になると読んだけど、どうやってそれを知るのか分からない。

私に正しい方向を教えてください。

+4

あなたのループが不足している、あなたが事前に割り当てボトルネックはおそらく 'rbf'関数でしょう。可能であれば、それをより速くする方法を決定するためには、その関数をプロファイリングする必要があります。 –

+1

'kernlab'に' rbf'関数はありません。どちらの機能が重複しているかを確認してください。たぶん、 'rbf < - rbfdot()'の結果でしょうか? –

+1

あなたの機能が占める時間の割合を測定してみてください( '?Rprof'を参照してください) – Seb

答えて

8

rbfが実際rbfdotへの呼び出しからの戻り値である場合、これのほとんどは、チェック機能で構成され、そしてあなただけのスカラに渡しているときcrossprodが簡単になりますので、その後body(rbf)は、

{ 
    if (!is(x, "vector")) 
     stop("x must be a vector") 
    if (!is(y, "vector") && !is.null(y)) 
     stop("y must a vector") 
    if (is(x, "vector") && is.null(y)) { 
     return(1) 
    } 
    if (is(x, "vector") && is(y, "vector")) { 
     if (!length(x) == length(y)) 
      stop("number of dimension must be the same on both data points") 
     return(exp(sigma * (2 * crossprod(x, y) - crossprod(x) - 
      crossprod(y)))) 
    } 
} 

ようになります私は、(R-2.14.0以降が必要)関数が可能、さらに高速化のために

rbf <- function(x, y, sigma = 1) 
{ 
    exp(- sigma * (x - y)^2) 
} 

のように簡単に考えて、compilerパッケージを使用します。

次に、rbf_loop_cmp(m, n)のタイミングを以前のものと比較してください。


簡略化の手順は、逆に分かりやすくなります。 expand(x - y)^2の場合はrbfの機能を除いたx^2 - 2 * x * y + y^2が得られます。

+0

あなたが持っているものに本当に単純化すれば、 「外側」。 –

+1

これはかなり印象的です。Richieの洞察のおかげで、私は巨大なパフォーマンスの向上を実現しました。実際、この関数はリッチーの言うことを簡素化し、一見して見ている(彼らはまったく同じ出力を出すが、私は二重チェックしなければならない)。これにより、speed()を作成するouter()を使用することができます。 'system.time({ 試験< - マトリックス(NaNで、nrow = 500、のNcoI = 1000)(I 1用 :500){1(jについて :1000){テスト[I、J (i、j){0(i、j)} } } system.time( test < - outer(1:500,1:1000、function j)^ 2)})) ' これは1877.333倍のスピードアップです! (168.96/0.09)。 – user1134616

+0

Richie CottonとJoshua Ulrichに感謝します! – user1134616

1

kernlab、 にそれは大きさ のためのカップル速くカーネル関数をループその後、夫婦でなければなりません)kernelMatrix(機能を使用します。

library(kernlab) 

rbf <- rbfdot(sigma=1) 

kernelMatrix(rbf, 1:5, 1:10) 
関連する問題