क्या कोई आर फ़ंक्शन है जो कोसाइन डिसिमिलरिटी मैट्रिक्स की गणना करेगा? [बन्द है]


20

मैं कॉशन दूरी के आधार पर पंक्ति क्लस्टरिंग के साथ हीटमैप बनाना चाहता हूं। मैं आर का उपयोग कर रहा हूं और heatmap.2()आंकड़ा बनाने के लिए। मैं देख सकता हूं कि इसमें एक distपैरामीटर है, heatmap.2लेकिन मुझे कॉशन डिसिमिलरिटी मैट्रिक्स उत्पन्न करने के लिए एक फ़ंक्शन नहीं मिल रहा है। बिल्टिन distफ़ंक्शन कोसाइन दूरियों का समर्थन नहीं करता है, मुझे arulesएक dissimilarity()फ़ंक्शन के साथ बुलाया गया पैकेज भी मिला लेकिन यह केवल बाइनरी डेटा पर काम करता है।


5
यह आपके अपने कोसाइन डिसिमिलरिटी फंक्शन को लिखने के लिए तेज़ हो सकता है।
१२

2
कोसाइन समानता है, असमानता नहीं। हालाँकि, आप कोसाइन को स्केल किए गए डेटा के यूक्लिडियन दूरी में बदल सकते हैं: d = sqrt (2 * (1-cos))।
ttnphns

SO पर समान प्रश्न: दो सरणियों के बीच
कोसिन

जवाबों:


29

जैसा कि @Max ने टिप्पणियों में दिखाया (+1) यह कहीं और समय बिताने की तुलना में "अपना खुद का" लिखना सरल होगा। जैसा कि हम जानते हैं, दो वैक्टर A , B की लंबाई n के बीच कोसाइन समानता हैA,Bn

C=i=1nAiBii=1nAi2i=1nBi2

में उत्पन्न करने के लिए सीधा है R। आज्ञा देना Xमैट्रिक्स जहां पंक्तियों मूल्यों हम के बीच समानता की गणना करना चाहते हैं हो सकता है। फिर हम निम्नलिखित Rकोड के साथ समानता मैट्रिक्स की गणना कर सकते हैं :

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)

तब मैट्रिक्स Cकोसाइन समानता समानता मैट्रिक्स है और आप इसे जो कुछ भी हीटमैप फ़ंक्शन को पसंद करते हैं उसे पास कर सकते हैं (केवल एक ही जो मैं परिचित हूं image())।


धन्यवाद, यह मददगार है। दरअसल, मैं मैट्रिक्स को स्वयं प्लॉट नहीं करना चाहता, बल्कि मेरे पास एक और हीटमैप के क्लस्टरिंग के लिए एक दूरी फ़ंक्शन है।
ग्रेग स्लोडकोविज़

@GregSlodkowicz, ठीक है शायद आप इस मैट्रिक्स को उस फ़ंक्शन को पास कर सकते हैं जिसका आप उपयोग कर रहे हैं। इसके अलावा, यदि आपको यह उत्तर उपयोगी लगा हो, तो कृपया एक अपवोट पर विचार करें (या यदि आप इसे निश्चित मानते हैं तो उत्तर को स्वीकार करें) :)
मैक्रो

महान, आपके उत्तर के लिए धन्यवाद और ttnphns की टिप्पणी मैं जो करना चाहता था वह करने में सक्षम था। अब मैं एक अलग मैट्रिक लेना चाहूंगा जब क्लस्टरिंग कॉलम की तुलना में पंक्तियों को क्लस्टर करना, लेकिन हो सकता है कि इसे धक्का दे रहा हो ...
ग्रेग स्लोडकोविज़

जाहिर तौर पर मेरे पास टिप्पणी करने में सक्षम होने के लिए पर्याप्त बिंदु नहीं हैं। मैं बस मैक्रों के अच्छे उत्तर के थोड़ा संशोधित संस्करण पेश करना चाहता था। यही पर है। # ChirazB का संस्करण mac.sim () मैक्रो द्वारा # जहां S = X% *% t (X) cos.sim.2 <- function (S, ix) {i <- ix [1] j <--ix ] वापसी (S [i, j] / sqrt (S [i, i] * S [j, j]))} #test X <- मैट्रिक्स (rnorm (20), nrow = 5, ncol = 4) S < - X% *% t (X) n <- nrow (X) idx.arr <- Expand.grid (i = 1: n, j = 1: n) C <- मैट्रिक्स (लागू करें (idx.arr, 1,) cos.sim, X), n, n) C2 <- मैट्रिक्स (लागू करें (idx.arr, 1, cos.sim.2, S), n), n) मुझे वैश्विक चर पसंद नहीं है, इसीलिए मैंने S शामिल किया एक पैरामीटर के रूप में।
चिराज़ बेनअबेल्डाकर


4

1-डी वैक्टर के बजाय मैट्रिस के साथ काम करते समय निम्नलिखित फ़ंक्शन उपयोगी हो सकता है:

# 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

ऊपर दिए गए कुछ उत्तर कम्प्यूटेशनल रूप से अक्षम हैं, इसे आज़माएं;


Cosine समानता मैट्रिक्स के लिए

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

कोसाइन डिसिमिलरिटी मैट्रिक्स (दूरी मैट्रिक्स) में बदलें।

D_sim <- as.dist(1 - sim)

0

इस मुद्दे पर पिछले कोड (@ मैक्रो) से कुछ को रैंप करके, हम इसे निम्नलिखित में क्लीनर संस्करण में लपेट सकते हैं:

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)

उम्मीद है की यह मदद करेगा!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.