मैट्रिक्स गुणा का उपयोग करके बाइनरी डेटा के लिए जैकार्ड या अन्य एसोसिएशन गुणांक की गणना करना


9

मैं जानना चाहता हूं कि क्या मैट्रिक्स गुणा का उपयोग करके जैककार्ड गुणांक की गणना करने का कोई संभावित तरीका है।

मैंने इस कोड का इस्तेमाल किया

    jaccard_sim <- function(x) {
    # initialize similarity matrix
    m <- matrix(NA, nrow=ncol(x),ncol=ncol(x),dimnames=list(colnames(x),colnames(x)))
    jaccard <- as.data.frame(m)

    for(i in 1:ncol(x)) {
     for(j in i:ncol(x)) {
        jaccard[i,j]= length(which(x[,i] & x[,j])) / length(which(x[,i] | x[,j]))
        jaccard[j,i]=jaccard[i,j]        
       }
     }

यह आर में लागू करने के लिए काफी ठीक है। मैंने पासा समानता को एक किया है, लेकिन टैनिमोटो / जैकार्ड के साथ फंस गया। कोई मदद कर सकता है?


ऐसा लगता है कि @ttnphns ने इसे कवर किया है, लेकिन जब से आप R का उपयोग कर रहे हैं, मैंने सोचा था कि मैं यह भी इंगित करूंगा कि veganपैकेज में पहले से ही कई समानता सूचक (जैकार्ड सहित) लागू हैं । मुझे लगता है कि वे गति के लिए बहुत अच्छी तरह से अनुकूलित होते हैं।
डेविड जे। हैरिस

जवाबों:


11

हम जानते हैं कि जैकार्ड ( बाइनरी डेटा के किसी भी दो कॉलम के बीच गणना की गई हैX) है aa+b+c, जबकि रोजर्स-तनीमोतो है a+da+d+2(b+c), कहाँ पे

  • a - पंक्तियों की संख्या जहां दोनों कॉलम 1 हैं
  • b - पंक्तियों की संख्या जहां यह है और अन्य कॉलम 1 नहीं है
  • c - पंक्तियों की संख्या जहां अन्य और यह कॉलम 1 नहीं है
  • d - पंक्तियों की संख्या जहाँ दोनों कॉलम 0 हैं

a+b+c+d=nमें पंक्तियों की संख्या X

तो हमारे पास हैं:

XX=A का वर्ग सममित मैट्रिक्स है a सभी स्तंभों के बीच।

(notX)(notX)=डी का वर्ग सममित मैट्रिक्स है सभी स्तंभों के बीच ("नहीं X" X में 1-> 0 और 0-> 1 को परिवर्तित कर रहा है)।

इसलिए, n-डी सभी स्तंभों के बीच जैकार्ड का वर्गाकार सममित मैट्रिक्स है।

+डी+डी+2(n-(+डी))=+डी2n--डी सभी स्तंभों के बीच रोजर्स-टैनिमोटो का वर्ग सममित मैट्रिक्स है।

मैंने संख्यात्मक रूप से जाँच की अगर ये सूत्र सही परिणाम देते हैं। वे करते हैं।


Upd। आप मैट्रिस भी प्राप्त कर सकते हैंबी तथा सी:

बी=[1]'एक्स-, जहां "[1]" लोगों के मैट्रिक्स को दर्शाता है, आकार के रूप में एक्सबी का वर्ग असममित मैट्रिक्स है सभी स्तंभों के बीच; इसका तत्व ij पंक्तियों की संख्या हैएक्सकॉलम I में 0 और कॉलम j में 1 के साथ ।

इसके फलस्वरूप, सी=बी'

आव्यूह डी इस तरह से भी गणना की जा सकती है: n--बी-सी

मत्रियों को जानना ,बी,सी,डी, आप द्विआधारी डेटा के लिए आविष्कार किए गए किसी भी जोड़ीदार (डिस) समानता गुणांक के मैट्रिक्स की गणना करने में सक्षम हैं।


जब तक वे लघुकरण नहीं करते, तब तक मैट्रिसेस के लिए कोई मतलब नहीं होता है: एक व्युत्क्रम द्वारा दाईं ओर गुणा करना अन्यथा बाईं ओर गुणा करने की तुलना में एक अलग परिणाम देगा। इसके अलावा, यह आमतौर पर ऐसा नहीं है कि दो सममित मैट्रिक्स का एक उत्पाद सममित है। क्या आप शायद घटक-दर-घटक विभाजन का मतलब है? क्या आप यह दर्शाने के लिए अपनी धारणा को ठीक कर सकते हैं कि आपका इरादा क्या है?
whuber

@ जब भी मैं उलटा इस्तेमाल नहीं करता और न ही चौकोर सममित मैट्रिसेस का गुणन नहीं करता । X बाइनरी डेटा मैट्रिक्स है और X'X इसका SSCP मैट्रिक्स है। not XX जहां 1-> 0, 0-> 1 है। और यहाँ कोई भी विभाजन तत्व-विभाजन है। कृपया मेरी सूचना को सही करें यदि आप देखें कि यह उचित नहीं है।
ttnphns

आर में आंतरिक उत्पाद (notX) ′ (notX) की गणना कैसे करें?
user4959

@ user4959, मुझे नहीं पता। यहाँ आर ! एक्स की सिफारिश की गई है हालाँकि परिणाम बूलियन TRUE / FALSE है, संख्यात्मक 1/0 नहीं। ध्यान दें कि मैंने अपना उत्तर अपडेट किया जहां मैं कहता हूं कि डी मैट्रिक्स में आने का एक और तरीका भी है।
ttnphns

9

यदि X विरल है तो उपरोक्त समाधान बहुत अच्छा नहीं है। क्योंकि! एक्स! एक घनी मैट्रिक्स बना देगा, जिसमें भारी मात्रा में मेमोरी और कम्प्यूटेशन होगा।

एक बेहतर उपाय है कि सूत्र जैकार्ड [i, j] = #common / (#i + #j - #common) का उपयोग किया जाए । विरल मैट्रिक्स के साथ आप इसे निम्नानुसार कर सकते हैं (ध्यान दें कि कोड गैर-विरल मैट्रिस के लिए भी काम करता है):

library(Matrix)
jaccard <- function(m) {
    ## common values:
    A = tcrossprod(m)
    ## indexes for non-zero common values
    im = which(A > 0, arr.ind=TRUE)
    ## counts for each row
    b = rowSums(m)

    ## only non-zero values of common
    Aim = A[im]

    ## Jacard formula: #common / (#i + #j - #common)
    J = sparseMatrix(
          i = im[,1],
          j = im[,2],
          x = Aim / (b[im[,1]] + b[im[,2]] - Aim),
          dims = dim(A)
    )

    return( J )
}

1

यह आपकी जरूरतों के आधार पर आपके लिए उपयोगी हो सकता है या नहीं भी हो सकता है। मान लें कि आप क्लस्टरिंग असाइनमेंट के बीच समानता में रुचि रखते हैं:

दो क्लस्टरिंग असाइनमेंट की समानता की गणना करने के लिए जैककार्ड समानता गुणांक या जैककार्ड इंडेक्स का उपयोग किया जा सकता है।

लेबलिंग को देखते हुए L1और L2, बेन-हर, एलिसेफ, और गयोन (2002) ने दिखाया है कि इंटरमीडिएट मैट्रिक्स के डॉट-उत्पादों का उपयोग करके जैकार्ड सूचकांक की गणना की जा सकती है। नीचे का कोड मेमोरी में इंटरमीडिएट मैट्रिसेस को स्टोर किए बिना जल्दी से जैकार्ड इंडेक्स की गणना करने के लिए इसका लाभ उठाता है ।

कोड C ++ में लिखा गया है, लेकिन sourceCppकमांड का उपयोग करके आर में लोड किया जा सकता है ।

/**
 * The Jaccard Similarity Coefficient or Jaccard Index is used to compare the
 * similarity/diversity of sample sets. It is defined as the size of the
 * intersection of the sets divided by the size of the union of the sets. Here,
 * it is used to determine how similar to clustering assignments are.
 *
 * INPUTS:
 *    L1: A list. Each element of the list is a number indicating the cluster
 *        assignment of that number.
 *    L2: The same as L1. Must be the same length as L1.
 *
 * RETURNS:
 *    The Jaccard Similarity Index
 *
 * SIDE-EFFECTS:
 *    None
 *
 * COMPLEXITY:
 *    Time:  O(K^2+n), where K = number of clusters
 *    Space: O(K^2)
 *
 * SOURCES:
 *    Asa Ben-Hur, Andre Elisseeff, and Isabelle Guyon (2001) A stability based
 *    method for discovering structure in clustered data. Biocomputing 2002: pp.
 *    6-17. 
 */
// [[Rcpp::export]]
NumericVector JaccardIndex(const NumericVector L1, const NumericVector L2){
  int n = L1.size();
  int K = max(L1);

  int overlaps[K][K];
  int cluster_sizes1[K], cluster_sizes2[K];

  for(int i = 0; i < K; i++){    // We can use NumericMatrix (default 0) 
    cluster_sizes1[i] = 0;
    cluster_sizes2[i] = 0;
    for(int j = 0; j < K; j++)
      overlaps[i][j] = 0;
  }

  //O(n) time. O(K^2) space. Determine the size of each cluster as well as the
  //size of the overlaps between the clusters.
  for(int i = 0; i < n; i++){
    cluster_sizes1[(int)L1[i] - 1]++; // -1's account for zero-based indexing
    cluster_sizes2[(int)L2[i] - 1]++;
    overlaps[(int)L1[i] - 1][(int)L2[i] - 1]++;
  }

  // O(K^2) time. O(1) space. Square the overlap values.
  int C1dotC2 = 0;
  for(int j = 0; j < K; j++){
    for(int k = 0; k < K; k++){
      C1dotC2 += pow(overlaps[j][k], 2);
    }
  }

  // O(K) time. O(1) space. Square the cluster sizes
  int C1dotC1 = 0, C2dotC2 = 0;
  for(int i = 0; i < K; i++){
    C1dotC1 += pow(cluster_sizes1[i], 2);
    C2dotC2 += pow(cluster_sizes2[i], 2);
  }

  return NumericVector::create((double)C1dotC2/(double)(C1dotC1+C2dotC2-C1dotC2));
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.