0

ツイートの累積頻度を含む N 個のベクトルがあります。明確にするために、これらのベクトルのいずれかが必要です (0、0、1、1、2、3、4、4、5、5、6、6、...)

ヒート マップを作成して、これらの周波数の違いを視覚化したかったのです。そのために、最初に、ツイート間のユークリッド距離を含む NxN 行列を作成したいと考えました。私の最初のアプローチはむしろ Java に似ており、次のようになります。

create_dist <- function(x){
  n <- length(x)                             #number of tweets
  xy <- matrix(nrow=n, ncol=n)               #create NxN matrix
  colnames(xy) <- names(x)                   #set column
  rownames(xy) <- names(x)                   #and row names

  for(i in 1:n) {
    for(j in 1:n){
      xy[i,j] <- distance(x[[i]], x[[1]])    #calculate euclidean distance for now, but should be interchangeable 
    }
  }

  xy
}

この距離マトリックスの作成にかかる時間を測定したところ、小さなサンプル (約 2,000 ツイート) の場合、すでに約 35 秒かかりました。

> system.time(create_dist(cumFreqs))
user  system elapsed 
34.572   0.000  34.602 

ここで、どうすれば計算を少し高速化できるかを考えました。私のコンピューターには 8 つのコアがあるため、並列化を使用すれば高速になるのではないかと考えました。

R 初心者のように、内側の for ループを foreach ループに変更しました。

#libraries
library(foreach)
library(doMC)
registerDoMC(4)

create_dist <- function(x){
  n <- length(x)                                #number of tweets
  xy <- matrix(nrow=n, ncol=n)                  #create NxN matrix
  colnames(xy) <- names(x)                      #set column
  rownames(xy) <- names(x)                      #and row names

  for(i in 1:n) {
    xy[i,] <- unlist(foreach(j=1:n) %dopar% {   #set each row of the matrix
      distance(x[[i]], x[[j]])
    })
  }

  xy
}

もう一度、system.time() を使用して 2000 ツイートのサンプルの距離行列を作成するのにかかる時間を測定したかったのですが、明らかに速度がまったく向上していないため、10 分後に実行をキャンセルしました。

解決策を探しましたが、残念ながら見つかりませんでした。ここで、この距離行列を作成するためのより良い方法、おそらく適用関数があるかどうかをお聞きしたいと思います。恥ずべきことではありませんが、まだ私を混乱させています。

4

2 に答える 2

2

前述のように、dist関数を使用できます。distの結果を使用してヒートマップを作成する方法の例を次に示します。

nn <- paste0('row',1:5)
x <- matrix(rnorm(25), nrow = 5,dimnames=list(nn))
distObj <- dist(x)
cols <- c("#D33F6A", "#D95260", "#DE6355", "#E27449", 
            "#E6833D", "#E89331", "#E9A229", "#EAB12A", "#E9C037", 
            "#E7CE4C", "#E4DC68", "#E2E6BD")
## mandatory coercion
distObj <- as.matrix(distObj)
## hetamap
image(distObj[order(nn), order(nn)], col = cols, 
      xaxt = "n", yaxt = "n")
## axes labels
axis(1, at = seq(0, 1, length.out = dim(distObj)[1]), labels = nn, 
     las = 2)
axis(2, at = seq(0, 1, length.out = dim(distObj)[1]), labels = nn, 
     las = 2)

ここに画像の説明を入力

于 2013-06-16T13:03:59.060 に答える
0

「agstudy」が示唆するように、組み込みの「dist」関数を使用します。

今後の参考のために、R のネストされた for ループはかなり遅いです。R は関数型言語であるため、apply ファミリ (apply、lapply、sapply、tapply) などの関数でベクトル化された操作を試してみてください。C に似たパラダイムに慣れていると、関数的な方法でプログラミング タスクを考えるのに時間がかかります。

for ループと apply フレーバーの間のベンチマークに関する有益な議論はここにあります: Is R's apply family more than syntactic sugar?

于 2013-07-04T13:35:37.487 に答える