2013-06-16 3 views
0

트윗의 누적 빈도가 포함 된 N 개의 벡터가 있습니다.이 벡터 중 하나는 (0, 0, 1, 1, 2, 3, 4, 4, 5, 5 , 6, 6, ...)병렬화를 사용하여 R로 거리 행렬을 만듭니다.

히트 맵을 만들어 이러한 빈도의 차이를 시각화하고 싶습니다. 이를 위해 먼저 트위터 간의 유클리드 거리를 포함하는 NxN 매트릭스를 만들고 싶습니다. 내 첫 번째 방법은 같은 자바 오히려이며, 다음과 같습니다

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 
} 

내가 이미 약 35 초 정도가이 거리 행렬을 작성하는 데 걸리는 시간을 측정하고, 작은 샘플 (이천 트윗 주위).
> system.time(create_dist(cumFreqs)) 
user system elapsed 
34.572 0.000 34.602 

지금 내가 계산을 좀 더 빨리 수있는 방법에 대해 생각하고 내 컴퓨터는 8 개 코어를 가지고 있기 때문에 내가 더 빨리 될 것 병렬화를 사용하는 경우 어쩌면 생각했다.

초보자처럼 나는 내부 루프를 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()를 사용하여 이천 트윗 (tweet)의 샘플에 대한 거리 행렬을 작성하는 데 걸리는 시간을 측정하고 싶어하지만, 분명히이 없기 때문에 나는 10 분 후에 실행을 취소 전혀 속도를 내라.

해결책을 찾았지만 불행히도 나는 아무것도 발견하지 못했습니다. 이제는이 거리 매트릭스를 만드는 더 좋은 방법이 있는지 물어보고 싶었습니다. 어쩌면 적용 함수를 적용 할 수도 있습니다. 나는 부끄럽지 않습니다. 아직도 혼란스러워합니다.

+2

왜'dist' 사용하지 않는? 당신의 솔루션보다 훨씬 더 빨라야합니다. – sgibb

+0

내부 루프가 아닌 외부 루프를 병렬화하면 성능이 향상 될 것이라고 생각합니다. 이점을 얻으려면 병렬화 오버 헤드가 있더라도 각 반복은 성능이 많이 필요합니다. 그러나 코드에서 모든 명시 적 R 루프를 제거 할 수 있다고 생각합니다 (@sgibb의 주석 참조). – Roland

+0

또는 거리 계산을 C++로 작성하고'inline' 패키지를 사용하여 R에 통합 할 수 있습니다. –

답변

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) 

enter image description here

+1

그래서'cumFreqs' 벡터리스트를 사용하면 다음과 같이 할 수 있습니다 : 'x <- do.call (rbind, cumFreqs)','distObj <- dist (x)'. 길이가 100 인 2000 개의 벡터로, 이것은 단지 2 초 걸립니다. – jbaums

+0

@jbaums 맞아! 나는 더 잘하지 않을 것이다. – agstudy

0

처럼 'agstudy는'내장 'DIST'기능을 사용하여 제안합니다.

향후 참조를 위해 R에서 중첩 된 for 루프는 매우 느립니다. R은 함수형 언어이므로 적용 계열 (apply, lapply, sapply, tapply)과 같은 함수로 벡터화 된 연산을 시도해보십시오. C와 같은 패러다임에 익숙해지면 기능적 방법으로 프로그래밍 작업을 생각하는 데 시간이 걸립니다.

유용한 for 루프 사이의 벤치 마크에 대한 토론과 풍미를 적용은 여기에 있습니다 :? Is R's apply family more than syntactic sugar?

관련 문제