StatsBeginner: 初学者の統計学習ノート

統計学およびR、Pythonでのプログラミングの勉強の過程をメモっていくノート。たまにMacの話題。

Rで距離行列を求める高速な関数

Rでクラスター分析などをするときに距離行列を求める必要があるが、次元が大きくなると(万単位とか)けっこう時間がかかる。
で、

  • 標準で入ってる{stats}のdist()
  • {Rfast}のDist()
  • {wordspace}のmatrix.dist()

を比較してみたところ、3つ目のやつが一番速く、100倍ぐらい高速になった。
以下は、5000行かける768列の元データに対して、各行のあいだの距離を求めた例です。
いずれも、いろんな距離を求めるオプションがあるが、{wordspace}のmatrix.distだけはデフォルトがコサイン類似度になってるので、ユークリッド距離にするならmethod='euclidean'をかく必要がある。

ちなみにstats::distの場合でいうと、1000行なら8秒だったのが、5000行にすると5分近くかかるようになるので、探索的に(階層的)クラスター分析をする上ではここの速度はかなり重要。

> t <- proc.time()
> distance <- stats::dist(mat)
> proc.time() - t
   user  system elapsed 
288.061   0.004 287.934 
> t <- proc.time()
> distance <- Rfast::Dist(mat)
> proc.time() - t
   user  system elapsed 
  7.982   0.000   7.979 
> t <- proc.time()
> distance <- wordspace::dist.matrix(mat, method='euclidean')
> proc.time() - t
   user  system elapsed 
  2.131   0.164   2.297 

細かい違いも一応メモっておく。

  • 入力データ
    • stats::distは、matrix型でもdata.frame型でもよい
    • Rfast::Distは、matrix型でもdata.frame型でもよい
    • wordspace::matrix.distは、は、matrix型じゃないとダメ
  • 出力データ(stats::hclustやfastcluster::hclustに与えるときの話*1
    • stats::distは、dist型なのでそのままhclustに与えてOK
    • Rfast::Distは、as.dist()してからhclustに与える
    • wordspace::matrix.distは、は、as.dist()してからhclustに与える
  • デフォルト
    • stats::distは、ユークリッド距離
    • Rfast::Distは、ユークリッド距離
    • wordspace::matrix.distは、コサイン類似度

*1:fastcluster::hclustは自分がやった範囲ではstats::hclustとあまり変わらない。