題:
R中的Jaccard相似性
Torvon
2015-10-12 22:23:22 UTC
view on stackexchange narkive permalink

我想比較兩個長度為43的向量;它們的值為0(不存在)和1(存在)。我將$ M_ {1,1} $稱為同時存在1的情況,將$ M_ {1,0} $和$ M_ {0,1} $稱為僅存在1的情況,而將其他值為0。

  data3 $ IDS 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0data3 $ CESD 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1  

我想了解這兩個向量之間的關係。閱讀有關該主題的 Jaccard索引似乎是一條路。在此特定情況下,Jaccard索引為(請注意,我使用的是維基百科第二個數字旁邊給出的公式):$$ \ frac {M_ {1,1}} {(M_ {1,0} + M_ {0,1}-M_ {1,1})} $$就我而言:$ 8 /(23 + 12-8)= 0.2962963 $

使用:

 庫('clusteval')群集相似性(data3 $ IDS,data3 $ CESD,相似性=“ jaccard”,method =“ independence”) 

返回:

  0.553429  

我不太清楚為什麼以及我犯的錯誤在哪裡。

我不了解的另一件事是在高度重疊的情況下。想像$ M_ {1,1} = 30 $,單元格$ M_ {1,0} $和$ M_ {0,1} $中每個值只有$ 2 $。這將導致Jaccard索引為$ 30 /(2 + 2-30)= -1.153846 $。

但是J索引僅在0到1之間定義。我的誤解在哪裡?

五 答案:
gung - Reinstate Monica
2015-10-13 07:23:30 UTC
view on stackexchange narkive permalink

查看Wikipedia頁面的編輯歷史記錄,看來問題出在對用於表示索引的兩種數學符號類型的混淆。使用集合論的符號,我們有:
$$ J(A,B)= \ frac {| A \ cap B |} {| A \ cup B |} = \ frac {| A \ cap B |} {| A | + | B | -|| A \ cap B |} $$,其中$ \ cap $表示交叉點,$ \ cup $表示 union,而$ \ lvert \ \ rvert $表示基數

下面,使用矩陣/列聯表$ M​​ $:
$$ J = \ frac {M_ {11}} {M_ {10} + M_ { 01} + M_ {11}} $$這似乎與一位編輯認為是“公式[sic]中的錯誤。應減去交點”的編輯相矛盾。

這兩個公式實際上是一致的,因為儘管$ | A \ cap B | = M_ {11} $,$ | A | \ ne M_ {10} $和$ | B | \ ne M_ { 01} $。代數公式可以這樣表示(比較麻煩,但更清楚地與頂部公式平行):
$$ J = \ frac {M_ {11}} {\ sum_j M_ {1j} + \ sum_i M_ {i1}-M_ {11}} $$

Peter Smit
2015-10-13 01:39:32 UTC
view on stackexchange narkive permalink

那個公式確實是錯誤的。

它應該是m11 /(m01 + m10 + m11),因為Jaccard索引是兩個集合之間的交集的大小除以那些集合之間的並集的大小。

正確值為8 /(12 + 23 + 8)= 0.186。但我覺得很奇怪,這與您從R包獲得的值不同。

您正確地理解了Jaccard索引是介於0和1之間的值。例如,您給出了正確的索引是30 /(2 + 2 + 30)= 0.882。

程序包有0和1的問題,並估計了錯誤的列聯表。到目前為止,我還無法找到原因,因此我使用更正的公式編寫了自己的J函數。軟件包“ ade4”中的dist.binary函數也可以用作超級按鈕(在這種情況下,請使用1-J)。
clusteval軟件包用於比較兩個聚類(分區),而不是兩個集合。用於比較集的“ Jaccard索引”假定0 =缺少集合,而1 =出現在集合中。如果您改為將0/1解釋為指示兩個可能的群集標籤,並且使用data3 $ IDS和data3 $ CESD作為單獨的群集,則clusteval會給出正確的答案。一種快速的檢查方法是,簇標籤對於排列是不變的,而存在/不存在不是。因此,反轉其中一個變量的0/1會更改基於集合的Jaccard,但不會更改聚類/ clusteval Jaccard。
jsb
2017-09-14 06:41:11 UTC
view on stackexchange narkive permalink

我寫了一個簡單的函數來計算Jaccard索引(相似係數)和二進制屬性的互補Jaccard距離:

 #您的數據集
df2 <- data.frame(
  IDS = c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0),
  CESD = c(1,1,1,0,1,1,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1))

#函數返回Jaccard索引和Jaccard距離
jaccard <- function(df,margin){
  if(margin == 1 | margin == 2){
    M_00 <- apply(df,margin,sum)== 0
    M_11 <- apply(df,margin,sum)== 2
    如果(保證金== 1){
      df <- df [!M_00,]
      JSim <- sum(M_11)/ nrow(df)
    }其他{
      df <- df [,!M_00]
      JSim <-和(M_11)/長度(df)
    }
    JDist <- 1-JSim
    return(c(JSim = JSim,JDist = JDist))
  } else break
}
 

該函數帶有兩個參數: x 一個數據框或矩陣對象,以及 m apply MARGIN 參數/ code>函數。如果您的數據採用寬格式,則將 m = 2 設置為對列應用 sum 。如果您的數據是長格式,請設置 m = 1 以對行應用 sum

  > jaccard(df2,1)
     Jim JDist
0.1860465 0.8139535
 
Torvon
2015-10-13 01:15:26 UTC
view on stackexchange narkive permalink

已解決。問題在於維基百科實際上是錯誤的,具體來說是公式:

m11 /(m10 + m01-m11)

bmc
2018-05-23 00:47:20 UTC
view on stackexchange narkive permalink

擴展@jsb的代碼以在所有觀察結果之間實現相似性度量。

 #Jaccar索引
圖書館(dplyr)

#您的數據集
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
df

#函數返回Jaccard索引和Jaccard距離
#參數:
#1. df,感興趣的數據幀
#2.邊距,apply函數沿其移動的軸
jaccard <- function(df,margin = 1){
  如果(保證金== 1 |保證金== 2){
    M_00 <- apply(df,margin,sum)== 0
    M_11 <- apply(df,margin,sum)== 2
    如果(保證金== 1){
      df <- df [!M_00,]
      JSim <- sum(M_11)/ nrow(df)
    }其他{
      df <- df [,!M_00]
      JSim <- sum(M_11)/ length(df)
    }
    JDist <- 1-JSim
    return(c(JSim = JSim,JDist = JDist))
  } else break
}

jaccard(df [1:2,],margin = 2)


jaccard_per_row <- function(df,margin = 1){
   要求(magrittr)
   要求(dplyr)
   key_pairs <- expand.grid(row.names(df),row.names(df))
   結果<- t(apply(key_pairs,1,function(row)jaccard(df [c(row [1],row [2]),],margin = margin)))
   key_pair <- key_pairs%>%mutate(pair = paste(Var1,“ _”,Var2,sep =“”))
   結果<- data.frame(結果)
   row.names(結果)<- key_pair $ pair
   結果
}

jaccard_per_row(df,margin = 2)
 

輸出:

  JSim JDist
c1_c1 1.0000000 0.0000000
c2_c1 0.3974359 0.6025641
c3_c1 0.3513514 0.6486486
c4_c1 0.3466667 0.6533333
c5_c1 0.3333333 0.6666667
c6_c1 0.3888889 0.6111111
c1_c2 0.3974359 0.6025641
c2_c2 1.0000000 0.0000000
c3_c2 0.3289474 0.6710526
c4_c2 0.4166667 0.5833333
c5_c2 0.3466667 0.6533333
c6_c2 0.3289474 0.6710526
c1_c3 0.3513514 0.6486486
c2_c3 0.3289474 0.6710526
c3_c3 1.0000000 0.0000000
c4_c3 0.2236842 0.7763158
c5_c3 0.3333333 0.6666667
c6_c3 0.3529412 0.6470588
c1_c4 0.3466667 0.6533333
c2_c4 0.4166667 0.5833333
c3_c4 0.2236842 0.7763158
c4_c4 1.0000000 0.0000000
c5_c4 0.3676471 0.6323529
c6_c4 0.2236842 0.7763158
c1_c5 0.3333333 0.6666667
c2_c5 0.3466667 0.6533333
c3_c5 0.3333333 0.6666667
c4_c5 0.3676471 0.6323529
c5_c5 1.0000000 0.0000000
c6_c5 0.2957746 0.7042254
c1_c6 0.3888889 0.6111111
c2_c6 0.3289474 0.6710526
c3_c6 0.3529412 0.6470588
c4_c6 0.2236842 0.7763158
c5_c6 0.2957746 0.7042254
c6_c6 1.0000000 0.0000000
 

現在,您可以確定閾值高於所需百分比的行,並且僅保留非常相似的觀察結果進行分析。

享受!



該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...