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とあまり変わらない。