Frage:
Jaccard Ähnlichkeit in R.
Torvon
2015-10-12 22:23:22 UTC
view on stackexchange narkive permalink

Ich möchte 2 Vektoren der Länge 43 vergleichen. Sie haben Werte von 0 (nicht vorhanden) und 1 (vorhanden). Ich werde $ M_ {1,1} $ als Situationen bezeichnen, in denen beide 1 vorhanden sind, und $ M_ {1,0} $ und $ M_ {0,1} $ als Situationen, in denen nur eine 1 vorhanden ist, während die Der andere Wert ist 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 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 1 0 1 0 0 1 0 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 1  

Ich möchte verstehen, wie verwandt diese beiden Vektoren sind. Der Jaccard -Index scheint der richtige Weg zu sein, um sich über das Thema zu informieren. In diesem speziellen Fall wäre der Jaccard-Index (beachten Sie, dass ich die Formel verwende, die neben der zweiten Zahl in Wikipedia angegeben ist): $$ \ frac {M_ {1,1}} {(M_ {1,0} + M_ {0,1} - M_ {1,1})} $$ In meinem Fall: $ 8 / (23 + 12 - 8) = 0,2962963 $

Verwenden von:

  library ('clusteval') cluster_similarity (Daten3 $ IDS, Daten3 $ CESD, Ähnlichkeit = "Jaccard", Methode = "Unabhängigkeit")  

Rückgabe:

  0.553429  

Ich kann nicht genau herausfinden, warum und wo der Fehler ist, den ich mache.

Eine andere Sache, die ich nicht verstehe, ist in Fällen hoher Überlappung. Stellen Sie sich $ M_ {1,1} = 30 $ mit jeweils nur $ 2 $ Werten in den Zellen $ M_ {1,0} $ und $ M_ {0,1} $ vor. Dies würde zu einem Jaccard-Index von 30 USD / (2 + 2-30) = -1,153846 USD führen.

Der J-Index wird jedoch nur zwischen 0 und 1 definiert. Wo liegt mein Missverständnis?

Fünf antworten:
gung - Reinstate Monica
2015-10-13 07:23:30 UTC
view on stackexchange narkive permalink

Wenn man sich den Bearbeitungsverlauf der Wikipedia-Seite ansieht, scheint das Problem auf eine Verwirrung über die beiden Arten der mathematischen Notation zurückzuführen zu sein, die zur Darstellung des Index verwendet werden. Unter Verwendung der Notation aus der Mengenlehre haben wir:
$$ J (A, B) = \ frac {| A \ cap B |} {| A \ cup B |} = \ frac {| A \ cap B |} {| A | + | B | - | A \ cap B |} $$ wobei $ \ cap $ die Kreuzung bezeichnet, $ \ cup $ die Vereinigung bezeichnet und $ \ lvert \ \ rvert $ bezeichnet die Kardinalität.

Unten wurde die Formel algebraisch unter Verwendung von Zählungen aus einer Matrix- / Kontingenztabelle $ M $ dargestellt:
$$ J = \ frac {M_ {11}} {M_ {10} + M_ { 01} + M_ {11}} $$ Dies schien einem Redakteur zu widersprechen, der kommentierte, dass es einen "Fehler in der Formel [sic]. Sollte minus der Schnittmenge sein".

Die beiden Formeln sind tatsächlich konsistent, denn obwohl $ | A \ cap B | = M_ {11} $, $ | A | \ ne M_ {10} $ und $ | B | \ ne M_ { 01} $. Die algebraische Formel hätte folgendermaßen dargestellt werden können (auf eine Weise, die umständlicher ist, aber deutlicher parallel zur oberen Formel):
$$ 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

Diese Formel ist in der Tat falsch.

Es sollte m11 / (m01 + m10 + m11) sein, da der Jaccard-Index die Größe des Schnittpunkts zwischen zwei Sätzen ist, geteilt durch die Größe der Vereinigung zwischen diesen Sätzen.

Der korrekte Wert ist 8 / (12 + 23 + 8) = 0,186. Ich finde es jedoch seltsam, dass dies nicht derselbe Wert ist, den Sie aus dem R-Paket erhalten.

Sie haben richtig verstanden, dass der Jaccard-Index ein Wert zwischen 0 und 1 ist. Für das Beispiel haben Sie den richtigen Index angegeben ist 30 / (2 + 2 + 30) = 0,882

Das Paket hat Probleme mit 0 und 1 und schätzt die falsche Kontingenztabelle.Ich konnte den Grund dafür noch nicht finden, also schrieb ich meine eigene J-Funktion mit der korrigierten Formel.Die dist.binary-Funktion aus dem Paket 'ade4' funktioniert ebenfalls wie ein Zauber (in diesem Fall verwenden Sie 1-J).
Das Clusteval-Paket dient zum Vergleichen von zwei Clustern (Partitionen) anstelle von zwei Sätzen.Der Jaccard-Index zum Vergleichen von Sätzen setzt 0 = Abwesenheit von Sätzen und 1 = Vorhandensein von Sätzen voraus.Wenn Sie stattdessen 0/1 so interpretieren, dass es die beiden möglichen Cluster-Labels angibt, wobei "data3 $ IDS" und "data3 $ CESD" als separate Cluster vorliegen, gibt clusteval die richtige Antwort.Eine schnelle Möglichkeit zur Überprüfung besteht darin, dass Cluster-Labels für die Permutation unveränderlich sind, während dies bei Anwesenheit / Abwesenheit nicht der Fall ist.Wenn Sie also die 0/1 in einer der Variablen umkehren, ändert sich die satzbasierte Jaccard, nicht jedoch die Clustering / Clusteval-Jaccard.
jsb
2017-09-14 06:41:11 UTC
view on stackexchange narkive permalink

Ich habe eine einfache Funktion zur Berechnung des Jaccard-Index (Ähnlichkeitskoeffizient) und des komplementären Jaccard-Abstands für binäre Attribute geschrieben:

  # Ihr Datensatz
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, 1, 0, 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, 0, 1, 0, 0, 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))

# Die Funktion gibt den Jaccard-Index und die Jaccard-Entfernung zurück
jaccard <- Funktion (df, Rand) {
  if (margin == 1 | margin == 2) {
    M_00 <- apply (df, margin, sum) == 0
    M_11 <- apply (df, margin, sum) == 2
    if (margin == 1) {
      df <- df [! M_00,]
      JSim <-sum (M_11) / nrow (df)
    } else {
      df <- df [,! M_00]
      JSim <-Summe (M_11) / Länge (df)
    }}
    JDist <-1 - JSim
    return (c (JSim = JSim, JDist = JDist))
  } sonst brechen
}}
 

Die Funktion akzeptiert zwei Argumente: x einen Datenrahmen oder ein Matrixobjekt und m das Argument MARGIN , das im apply Funktion. Wenn Ihre Daten im Breitformat vorliegen, setzen Sie m = 2 , um sum auf die Spalten anzuwenden. Wenn Ihre Daten im Langformat vorliegen, setzen Sie m = 1 , um sum auf die Zeilen anzuwenden.

  > jaccard (df2, 1)
     JSim JDist
0,1860465 0,8139535
 
Torvon
2015-10-13 01:15:26 UTC
view on stackexchange narkive permalink

Gelöst. Das Problem war, dass Wikipedia tatsächlich falsch ist, insbesondere die Formel:

m11 / (m10 + m01-m11)

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

Erweiterung des Codes von @ jsb, um ein Ähnlichkeitsmaß für alle Beobachtungen zu ermöglichen.

  # Jaccar Index
Bibliothek (dplyr)

# Ihr Datensatz
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

# Die Funktion gibt den Jaccard-Index und die Jaccard-Entfernung zurück
# Parameter:
# 1. df, Datenrahmen von Interesse
# 2. Rand, Achse, in der sich die Apply-Funktion bewegen soll
jaccard <- Funktion (df, margin = 1) {
  if (margin == 1 | margin == 2) {
    M_00 <- anwenden (df, margin, sum) == 0
    M_11 <- anwenden (df, margin, sum) == 2
    if (margin == 1) {
      df <- df [! M_00,]
      JSim <-sum (M_11) / nrow (df)
    } else {
      df <- df [,! M_00]
      JSim <-Summe (M_11) / Länge (df)
    }}
    JDist <-1 - JSim
    return (c (JSim = JSim, JDist = JDist))
  } sonst brechen
}}

Jaccard (df [1: 2,], Rand = 2)


jaccard_per_row <- Funktion (df, margin = 1) {
   benötigen (magrittr)
   erfordern (dplyr)
   key_pairs <- expand.grid (row.names (df), row.names (df))
   Ergebnisse <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 = ""))
   Ergebnisse <- data.frame (Ergebnisse)
   row.names (results) <- key_pair $ pair
   Ergebnisse
}}

jaccard_per_row (df, margin = 2)
 

Ausgabe:

  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
 

Jetzt können Sie bestimmen, welche Zeilen einen Schwellenwert über einem gewünschten Prozentsatz haben, und nur sehr ähnliche Beobachtungen für Ihre Analyse aufbewahren.

Viel Spaß!



Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...