Calcolo dell'indice di Rand


17

Sto cercando di capire come calcolare l'indice Rand di un algoritmo di cluster, ma sono bloccato al punto come calcolare i veri e falsi negativi.

Al momento sto usando l'esempio del libro An Introduction in Information Retrieval (Manning, Raghavan & Schütze, 2009). A pagina 359 parlano di come calcolare l'indice Rand. Per questo esempio usano tre cluster e i cluster contengono i seguenti oggetti.

  1. aaaaab
  2. abbbbc
  3. aaccc

Sostituisco l'oggetto (segni originali in lettere, ma l'idea e il conteggio rimangono gli stessi). Fornirò le parole esatte del libro per vedere di cosa stanno parlando:

Per prima cosa calcoliamo TP + FP. I tre cluster contengono rispettivamente 6, 6 e 5 punti, quindi il numero totale di "positivi" o coppie di documenti che si trovano nello stesso cluster è:

TP + FP = (62) + (62) + (52) = 15 + 15+ 10 = 40

Di questi, le coppie a nel cluster 1, le coppie b nel cluster 2, le coppie c nel cluster 3 e la coppia a nel cluster 3 sono veri positivi:

TP = (52) + (42) + (32) + (22) = 10 + 6 + 3 + 1 = 20

Pertanto, FP = 40 - 20 = 20.

Fin qui i calcoli sono chiari, e se prendo altri esempi ottengo gli stessi risultati, ma quando voglio calcolare il falso negativo e il vero negativo Manning et al. dichiarare quanto segue:

FN e TN sono calcolati in modo simile, risultando nella seguente tabella di contingenza:

La tabella di contingenza ha il seguente aspetto:

+--------+--------+
| TP: 20 | FN: 24 |
+--------+--------+
| FP: 20 | TN: 72 |
+--------+--------+

La frase: "FN e TN sono calcolati in modo simile" non è chiara alla mia e non capisco di quali numeri ho bisogno per calcolare TN e FN. Posso calcolare il lato destro della tabella procedendo come segue:

TP + FP + FN + TN = = = 136(n2)(172)

Fonte: http://en.wikipedia.org/wiki/Rand_index

Quindi, FN + TN = 136 - TP + FP = 136 - 40 = 96, ma questo non aiuta davvero il mio a capire come calcolare le variabili separatamente. Soprattutto quando gli autori dicono: "FN e TN sono calcolati in modo simile". Non vedo come. Inoltre, quando guardo altri esempi, calcolano ogni cella della tabella di contingenza osservando ciascuna coppia.

Ad esempio: http://www.otlet-institute.org/wikics/Clustering_Problems.html#toc-Subsection-4.1

La mia prima domanda, basata sull'esempio di Manning et al (2009), è possibile calcolare TN e FN se si conoscono solo TP e NP? E se è così, come appare il calcolo simile basato sull'esempio dato?

Risposte:


9

Stavo riflettendo sullo stesso, e l'ho risolto in questo modo. Supponiamo di avere una tabella di contingenza / tabella di contingenza in cui le righe sono i cluster di verità di base e le colonne sono i cluster trovati dall'algoritmo di clustering.

Quindi, per l'esempio nel libro, sembrerebbe:

  | 1 | 2 | 3
--+---+---+---
x | 5 | 1 | 2
--+---+---+---
o | 1 | 4 | 0
--+---+---+---
◊ | 0 | 1 | 3

Ora, puoi facilmente calcolare il TP + FP prendendo la somma per colonna e 'scegli 2' su tutti questi valori. Quindi le somme sono [6, 6, 5] e fai '6 scegli 2' + '6 scegli 2' + '5 scegli 2'.

Ora, in effetti, allo stesso modo, puoi ottenere TP + FN prendendo la somma sopra le righe (quindi, cioè [8, 5, 4] nell'esempio sopra), applica 'scegli 2' su tutti quei valori e prendi il somma di quello.

I TP stessi possono essere calcolati applicando "scegli 2" a ogni cella della matrice e prendendo la somma di tutto (supponendo che "1 scegli 2" sia 0).

In effetti, ecco un codice Python che fa esattamente questo:

import numpy as np
from scipy.misc import comb

# There is a comb function for Python which does 'n choose k'                                                                                            
# only you can't apply it to an array right away                                                                                                         
# So here we vectorize it...                                                                                                                             
def myComb(a,b):
  return comb(a,b,exact=True)

vComb = np.vectorize(myComb)

def get_tp_fp_tn_fn(cooccurrence_matrix):
  tp_plus_fp = vComb(cooccurrence_matrix.sum(0, dtype=int),2).sum()
  tp_plus_fn = vComb(cooccurrence_matrix.sum(1, dtype=int),2).sum()
  tp = vComb(cooccurrence_matrix.astype(int), 2).sum()
  fp = tp_plus_fp - tp
  fn = tp_plus_fn - tp
  tn = comb(cooccurrence_matrix.sum(), 2) - tp - fp - fn

  return [tp, fp, tn, fn]

if __name__ == "__main__":
  # The co-occurrence matrix from example from                                                                                                           
  # An Introduction into Information Retrieval (Manning, Raghavan & Schutze, 2009)                                                                       
  # also available on:                                                                                                                                   
  # http://nlp.stanford.edu/IR-book/html/htmledition/evaluation-of-clustering-1.html                                                                     
  #                                                                                                                                                      
  cooccurrence_matrix = np.array([[ 5,  1,  2], [ 1,  4,  0], [ 0,  1,  3]])

  # Get the stats                                                                                                                                        
  tp, fp, tn, fn = get_tp_fp_tn_fn(cooccurrence_matrix)

  print "TP: %d, FP: %d, TN: %d, FN: %d" % (tp, fp, tn, fn)

  # Print the measures:                                                                                                                                  
  print "Rand index: %f" % (float(tp + tn) / (tp + fp + fn + tn))

  precision = float(tp) / (tp + fp)
  recall = float(tp) / (tp + fn)

  print "Precision : %f" % precision
  print "Recall    : %f" % recall
  print "F1        : %f" % ((2.0 * precision * recall) / (precision + recall))

Se lo eseguo ottengo:

$ python testCode.py
TP: 20, FP: 20, TN: 72, FN: 24
Rand index: 0.676471
Precision : 0.500000
Recall    : 0.454545
F1        : 0.476190

In realtà non ho controllato altri esempi oltre a questo, quindi spero di averlo fatto bene .... ;-)


Ty for answer ma non spieghi. dici entrambe le volte in base alla colonna. puoi aggiornare la tua risposta e includere FN + TN come hai fatto FP + TP
MonsterMMORPG

Non ho capito perché per TP '2 scegli 2' è considerato. Non significa che x è erroneamente classificato come ◊?
vcosk,

non intendi "somma sopra le righe" per TP + FN?
Zython,

Mi dispiace, si hai ragione. Risolto il problema nella risposta.
Tom,

6

Dopo aver studiato le altre risposte in questo thread, ecco la mia implementazione di Python, che accetta array come input, in sklearnstile:

import numpy as np
from scipy.misc import comb

def rand_index_score(clusters, classes):

    tp_plus_fp = comb(np.bincount(clusters), 2).sum()
    tp_plus_fn = comb(np.bincount(classes), 2).sum()
    A = np.c_[(clusters, classes)]
    tp = sum(comb(np.bincount(A[A[:, 0] == i, 1]), 2).sum()
             for i in set(clusters))
    fp = tp_plus_fp - tp
    fn = tp_plus_fn - tp
    tn = comb(len(A), 2) - tp - fp - fn
    return (tp + tn) / (tp + fp + fn + tn)

In [319]: clusters
Out[319]: [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]

In [320]: classes
Out[320]: [0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 2, 1, 0, 2, 2, 2, 0]

In [321]: rand_index_score(clusters, classes)
Out[321]: 0.67647058823529416

4

Non sono abbastanza sicuro di me stesso, ma è così che ho fatto il valore
TN : TN = (7 2) (10 2) (4 2)

(7 2) - Cluster 1 - il test dice 'x', quindi conta quelli che NON sono x (e sono correttamente raggruppati nei cluster 2 e 3)

vale a dire 4 'o + 3' d (diamanti) = (7 2)

(10 2) - Cluster 2, conta quelli che NON sono 'o' e correttamente raggruppati nei cluster 1 e 3,

cioè 5 'x' + (2'x '+ 3'd') = (10 2)

(4 2) - Cluster 3, conta quelli NON 'x' e NOT 'd' (elemento a forma di diamante) che sono correttamente raggruppati nei cluster 1 e 2.

cioè 4 'o's nel cluster 2. = (4 2)

TN = (7 2) + (10 2) + (4 2) = 72.

Quindi FN è:

FN = (17 2) - (TP + FP) - TN = 136-40-72 = 24. ---> (17 = numero totale di documenti)


Questa è la risposta che ha più senso per me, anche se in realtà non mostra come "FN e TN siano calcolati in modo simile", come dice il libro e la domanda si riferisce. Ho il sospetto che potrebbe esserci un modo più semplice, come forse la risposta che menziona i cluster / le classi che cambiano strategia suggerisce.
cjauvin,

Questo è sbagliato, questa descrizione non funziona in altri esempi. Restituisci il mio voto! La risposta corretta è di @ user9668.
Özgür,

Questa risposta in realtà ha perfettamente senso.
EhsanF,

2

Prendendo l'esempio di un'altra domanda:

  | 1 | 2 | 3
--+---+---+---
x | 5 | 1 | 2
--+---+---+---
o | 1 | 4 | 0
--+---+---+---
◊ | 0 | 1 | 3

La risposta ragionevole per FN:

FN = (c(8,2)-c(5,2)-c(2,2))+(c(5,2)-c(4,2))+(c(4,2)-c(3,2))=24  

Spiegazione:

  • (C (8,2) -c (5,2) -c (2,2))

    scegli 2 tra 8 per 'x' (a) la combinazione della stessa classe negli stessi cluster (c (5,2) per il cluster 1 ec (2,2) per il cluster 3),

  • (C (5,2) -c (4,2))

    scegli 2 tra 5 'o' (b) meno la combinazione della stessa classe negli stessi cluster (c (4,2) per il cluster 2)

  • (C (4,2) -c (3,2)

    scegli 2 da 4 per '◇' (c) meno la combinazione della stessa classe negli stessi cluster (c (3,2) per il cluster 3)

L'ho derivato così.


1

Ho un'implementazione di questo in R che spiegherò:

TP (a nel codice) è la somma di ogni cella scegli 2. Secondo la domanda originale (0 o 1 scegli 2 pari a 0)

FN (b) è la somma di ogni riga scegliere 2, tutte sommate, meno TP. Dove ogni somma delle righe rappresenta il numero di documenti in ciascuna classe True.

La somma di questo è tutti i documenti che sono simili e nello stesso cluster (TP) più tutti i documenti che sono simili e non sono nello stesso cluster (FN).

Quindi questo è (TP + FN) - TP = FN

FP (c) è calcolato in modo simile. La somma di ogni colonna sceglie 2, tutte sommate, meno TP. In questo caso ogni somma di colonna rappresenta il numero di documenti in ciascun cluster.

Quindi la somma di questo è tutti i documenti che sono simili e nello stesso cluster (TP) più tutti i documenti che non sono simili e si trovano nello stesso cluster (FP).

Quindi questo è (TP + FP) - TP = FP

Con questi 3 calcolati, il restante calcolo di TN è semplice. La somma della tabella scegli 2, meno TP, FP & FN = TN (d)

L'unica domanda che ho con questo metodo è la definizione di TP. Usando la terminologia in questa domanda, non capisco perché le 2 a nel cluster 3 siano considerate TP. Ho trovato questo sia qui che nel relativo libro di testo. Tuttavia capisco il loro calcolo supponendo che il loro calcolo TP sia corretto.

Spero che sia di aiuto

FMeasure = function (x, y, beta) 
{
  x <- as.vector(x)
  y <- as.vector(y)
  if (length(x) != length(y)) 
    stop("arguments must be vectors of the same length")
  tab <- table(x, y)
  if (all(dim(tab) == c(1, 1))) 
    return(1)
  a <- sum(choose(tab, 2))
  b <- sum(choose(rowSums(tab), 2)) - a
  c <- sum(choose(colSums(tab), 2)) - a
  d <- choose(sum(tab), 2) - a - b - c
  ## Precision
  P = a / (a + c)
  ## Recall
  R = a / (a + b)
  ##F-Measure
  Fm <- (beta^2 + 1) * P * R / (beta^2*P + R)
  return(Fm)
}

Questo è così di moda, cosa intendi con dell, riga, colonna?
Özgür,

Non sono sicuro del motivo per cui stai descrivendo la statistica Rand come voga? Le celle, le righe e le colonne si riferiscono alle righe e alle colonne delle celle della matrice di confusione. Secondo la domanda del PO.
SamPassmore,

Bene, perché non c'è una matrice di confusione nella domanda originale? e da nessuna parte hai affermato che è la matrice di confusione. È nella prima risposta sopra e una volta usato, sì, il tuo metodo sembra funzionare.
Özgür,

0

È possibile calcolare TN e FN allo stesso modo.

Basta cambiare i ruoli di etichette e cluster .

a) 1 1 1 1 1 2 3 3
b) 1 2 2 2 2
c) 2 3 3 3 3

... quindi esegui gli stessi calcoli.


Puoi essere più esplicito? Inoltre, ne hai altri 3 nella tua lista (c) credo, poiché dovrebbero esserci 17 articoli.
cjauvin,

risposta molto chiara
MonsterMMORPG

0

PENSO di aver invertito il falso negativo (FN). Per i veri positivi, hai creato 4 gruppi positivi. Nel cluster 1, avevi le cinque a; nel cluster 2, avevi le 4 b; nel cluster 3 c'erano le 3 c e le 2 a.

Quindi per il falso negativo.

  1. Inizia con le a nel cluster 1; ci sono 5 a posizionate correttamente nel cluster 1. Hai 1 false a nel cluster 2 e due false a nel cluster 3. Questo dà (5 1) e (5 2).
  2. Quindi per la b. Ci sono 4 b posizionate correttamente che hai calcolato in precedenza. Hai una falsa b nel cluster 1, e il gioco è fatto. Questo ti dà (4 1) per le b.
  3. Quindi per la c. Hai un falso c nel cluster 2, con tre corretti nel cluster 3, quindi c'è (3 1).
  4. Dopodiché, non possiamo dimenticare quella coppia di a nel cluster 3 che abbiamo definito un vero positivo. Quindi, rispetto a ciò, abbiamo 1 false a nel cluster 2. Anche se ci sono altre a nel cluster 1, non possiamo chiamarle false a perché ce ne sono così tante.

Pertanto, hai (5 1) + (5 2) + (4 1) + (3 1) + (2 1) che equivale a 5 + 10 + 4 + 3 + 2 = 24. Ecco da dove viene il 24, quindi sottraete che dai 136 avete già trovato il vero neg (TN).


0

Ecco come calcolare ogni metrica per l'indice Rand senza sottrarre

Note a margine per una più facile comprensione:

1) L'indice Rand si basa sul confronto di coppie di elementi. La teoria suggerisce che coppie simili di elementi dovrebbero essere collocate nello stesso cluster, mentre coppie diverse di elementi dovrebbero essere collocate in cluster separati.

2) Il RI non si preoccupa della differenza nel numero di cluster. Si preoccupa solo delle coppie di elementi Vero / Falso.

Sulla base di questo presupposto, viene calcolato l'indice Rand

inserisci qui la descrizione dell'immagine

Ok, tuffiamoci qui è il nostro esempio:

  | 1 | 2 | 3
--+---+---+---
x | 5 | 1 | 2
--+---+---+---
o | 1 | 4 | 0
--+---+---+---
◊ | 0 | 1 | 3

Nel denominatore, abbiamo un totale di coppie possibili, che è (17 2) = 136

Ora consente di calcolare ogni metrica per una migliore comprensione:

A) Cominciamo con un facile , ( Veri positivi o corretti simili )

Significa che devi trovare tutte le possibili coppie di elementi, in cui predizione ed etichetta vera sono state messe insieme. Nell'esempio della griglia significa ottenere la somma delle coppie possibili all'interno di ciascuna cella.

a = (5 2) + (1 2) + (2 2) + (1 2) + (4 2) + (0 2) + (0 2) + (1 2) + (3 2) = 
  = 10 + 0 + 1 + 0 + 6 + 0 + 0 + 0 + 3 = 20

C) Ora, facciamo c ( falsi positivi o dissimili errati )

Significa, trovare tutte le coppie, che abbiamo messo insieme, ma che dovrebbero essere in diversi cluster. Nell'esempio di griglia significa che trova tutte le possibili coppie tra 2 celle orizzontali

c = 5*1 + 5*2 + 1*2 + 
  + 1*4 + 1*0 + 4*0 + 
  + 0*1 + 0*3 + 1*3 = 
  = 5 + 10 + 2 + 4 + 0 + 0 + 0 + 0 + 3 = 24

D) Calcolo d ( Falso negativo o simile errato ) Significa, trovare tutte le coppie che abbiamo posizionato in diversi cluster, ma che dovrebbero essere insieme. Nell'esempio della griglia, trova tutte le possibili coppie tra 2 celle verticali

d = 5*1 + 5*0 + 1*0 + 
  + 1*4 + 1*1 + 4*1 + 
  + 2*0 + 2*3 + 0*3 = 
  = 5 + 0 + 0 + 4 + 1 + 4 + 0 + 6 + 0 = 20

B) E, infine, facciamo b ( Veri negativi o correggere diversamente )

Vuol dire, trova tutte le coppie che abbiamo inserito in diversi cluster, che dovrebbero anche trovarsi in diversi cluster. Sulla griglia, significa trovare tutte le possibili coppie tra 2 celle non verticali e non orizzontali

Ecco quali numeri devono essere moltiplicati, per capire meglio cosa intendevo:

d = x1*o2 + x1*o3 + x1*◊2 + x1*◊3 + 
  + x2*o1 + x2*o3 + x2*◊1 + x2*◊3 + 
  + x3*o1 + x3*o2 + x3*◊1 + x3*◊2 + 
  + o1*◊2 + o1*◊3 + 
  + o2*◊1 + o2*◊3 + 
  + o3*◊1 + o3*◊2

In numeri:

d = 5*4 + 5*0 + 5*1 + 5*3 + 
  + 1*1 + 1*0 + 1*0 + 1*3 + 
  + 2*1 + 2*4 + 2*0 + 2*1 + 
  + 1*1 + 1*3 +
  + 4*0 + 4*3 = 72

E alla fine l'Indice Rand è uguale: (20 + 72) / 136 = 0.676


0

Di seguito l'immagine che descrive la tua domanda:

Rand-Index-Question

Per risolvere questo problema, devi considerare questa matrice:

+--------------------------------+--------------------------------------+
| TP:                            | FN:                                  |
| Same class + same cluster      | Same class + different clusters      |
+--------------------------------+--------------------------------------+
| FP:                            | TN:                                  |
| different class + same cluster | different class + different clusters |
+--------------------------------+--------------------------------------+

Ecco come calcoliamo TP, FN, FP per l'indice Rand:

Calcolo TP, FN e FP per l'indice Rand

NOTA: Nelle equazioni precedenti, ho usato un triangolo per mostrare il diamante nella foto.

Ad esempio, per False Negative, dovremmo scegliere dalla classe ma in diversi cluster. Quindi, possiamo scegliere

  • 1 X dal cluster 1 e 1 X dal cluster 2 = (51)(11)=5
  • 1 X dal cluster 1 e 1 X dal cluster 3 = (51)(21)=10
  • 1 O dal cluster 1 e 1 O dal cluster 2 = (11)(41)=4
  • 1 X dal cluster 2 e 1 X dal cluster 3 = (11)(21)=2
  • 1 dal cluster 2 e 1 dal cluster 3 = (11)(31)=3

Finalmente avremo 24 (=5+10+4+2+3) stati.

Lo stesso vale per il resto delle equazioni.

La parte più difficile è TN che può essere eseguita come nella figura seguente:

Calcolo TN per l'indice Rand

Ci sono alcuni percorsi più brevi per calcolare l'indice Rand, ma è il calcolo in profondità e passo dopo passo. Infine, la tabella di contingenza ha il seguente aspetto:

+--------+--------+
| TP: 20 | FN: 24 |
+--------+--------+
| FP: 20 | TN: 72 |
+--------+--------+
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.