Có một hàm R sẽ tính toán ma trận độ không tương tự cosin không? [đóng cửa]


19

Tôi muốn tạo một bản đồ nhiệt với phân cụm hàng dựa trên khoảng cách cosin. Tôi đang sử dụng R và heatmap.2()để tạo ra con số. Tôi có thể thấy rằng có một disttham số trong heatmap.2nhưng tôi không thể tìm thấy một hàm để tạo ma trận độ không tương tự cosin. Hàm dựng sẵn distkhông hỗ trợ khoảng cách cosine, tôi cũng tìm thấy một gói được gọi arulesvới dissimilarity()hàm nhưng nó chỉ hoạt động trên dữ liệu nhị phân.


5
Nó có thể nhanh hơn để viết chức năng khác biệt cosine của riêng bạn.
giả định

2
Cosine là tương đồng, không giống nhau. Tuy nhiên, bạn có thể biến cosine thành khoảng cách euclide của dữ liệu được chia tỷ lệ: d = sqrt (2 * (1-cos)).
ttnphns

Câu trả lời:


28

Như @Max đã chỉ ra trong các nhận xét (+1), việc viết "của riêng bạn" sẽ đơn giản hơn so với việc dành thời gian tìm kiếm nó ở một nơi khác. Như chúng ta đã biết, độ tương tự cosin giữa hai vectơ có độ dài lànMột,Bn

C= =Σtôi= =1nMộttôiBtôiΣtôi= =1nMộttôi2Σtôi= =1nBtôi2

đó là đơn giản để tạo ra trong R. Hãy Xlà ma trận trong đó các hàng là các giá trị chúng ta muốn tính toán độ tương tự giữa. Sau đó, chúng ta có thể tính toán ma trận tương tự với Rđoạn mã sau :

cos.sim <- function(ix) 
{
    A = X[ix[1],]
    B = X[ix[2],]
    return( sum(A*B)/sqrt(sum(A^2)*sum(B^2)) )
}   
n <- nrow(X) 
cmb <- expand.grid(i=1:n, j=1:n) 
C <- matrix(apply(cmb,1,cos.sim),n,n)

Sau đó, ma trận Clà ma trận tương tự cosine và bạn có thể chuyển nó tới bất kỳ chức năng bản đồ nhiệt nào bạn thích (cách duy nhất tôi quen thuộc là image()).


Cảm ơn, điều này rất hữu ích. Trên thực tế, tôi không muốn vẽ sơ đồ ma trận mà thay vào đó có một hàm khoảng cách để phân cụm một bản đồ nhiệt khác mà tôi có.
Greg Slodkowicz

@GregSlodkowicz, có lẽ bạn có thể truyền ma trận này cho hàm bạn đang sử dụng. Ngoài ra, nếu bạn thấy câu trả lời này hữu ích, vui lòng xem xét một upvote (hoặc chấp nhận câu trả lời nếu bạn cho rằng nó dứt khoát) :)
Macro

Tuyệt vời, nhờ trả lời của bạn và nhận xét của ttnphns tôi đã có thể làm những gì tôi muốn. Bây giờ tôi muốn có một số liệu khác nhau khi phân cụm các hàng so với khi phân cụm các cột nhưng có lẽ điều đó đang đẩy nó ...
Greg Slodkowicz

Rõ ràng tôi không có đủ điểm để có thể bình luận. Tôi chỉ muốn cung cấp một phiên bản sửa đổi nhỏ của câu trả lời hay của Macro. Nó đây rồi # ChirazB là phiên bản cos.sim () của Macro # trong đó S = X% *% t (X) cos.sim.2 <- function (S, ix) {i <- ix [1] j <- ix [2 ] return (S [i, j] / sqrt (S [i, i] * S [j, j]))} #test X <- matrix (rnorm (20), nrow = 5, ncol = 4) S < - X% *% t (X) n <- nrow (X) idx.arr <- extend.grid (i = 1: n, j = 1: n) C <- matrix (áp dụng (idx.arr, 1, cos.sim, X), n, n) C2 <- matrix (áp dụng (idx.arr, 1, cos.sim.2, S), n, n) Tôi không thích biến toàn cục, đó là lý do tại sao tôi bao gồm S như một tham số.
Chiraz BenAbdelkader


4

Hàm sau có thể hữu ích khi làm việc với ma trận, thay vì vectơ 1-d:

# input: row matrices 'ma' and 'mb' (with compatible dimensions)
# output: cosine similarity matrix

cos.sim=function(ma, mb){
  mat=tcrossprod(ma, mb)
  t1=sqrt(apply(ma, 1, crossprod))
  t2=sqrt(apply(mb, 1, crossprod))
  mat / outer(t1,t2)
}

4

Một số câu trả lời ở trên là tính toán không hiệu quả, hãy thử điều này;


Đối với ma trận tương tự cosin

Matrix <- as.matrix(DF)
sim <- Matrix / sqrt(rowSums(Matrix * Matrix))
sim <- sim %*% t(sim)

Chuyển đổi sang ma trận không tương đồng cosine (ma trận khoảng cách).

D_sim <- as.dist(1 - sim)

0

Tăng cường một số mã trước đó (từ @Macro) về vấn đề này, chúng tôi có thể gói mã này thành phiên bản sạch hơn sau:

df <- data.frame(t(data.frame(c1=rnorm(100),
                              c2=rnorm(100),
                              c3=rnorm(100),
                              c4=rnorm(100),
                              c5=rnorm(100),
                              c6=rnorm(100))))

#df[df > 0] <- 1
#df[df <= 0] <- 0



apply_cosine_similarity <- function(df){
  cos.sim <- function(df, ix) 
  {
    A = df[ix[1],]
    B = df[ix[2],]
    return( sum(A*B)/sqrt(sum(A^2)*sum(B^2)) )
  }   
  n <- nrow(df) 
  cmb <- expand.grid(i=1:n, j=1:n) 
  C <- matrix(apply(cmb,1,function(cmb){ cos.sim(df, cmb) }),n,n)
  C
}
apply_cosine_similarity(df)

Hi vọng điêu nay co ich!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.