2017-12-09 8 views
0

Ich versuche, die ARI zwischen zwei Sätzen von Clustern zu berechnen, mit diesem Code:Computing Angepasst Rand Index

#computes ARI for this type of clustering 
def ARI(table,n): 

index = 0 
sum_a = 0 
sum_b = 0 
for i in range(len(table)-1): 
    for j in range(len(table)-1): 
     sum_a += choose(table[i][len(table)-1],2) 
     sum_b += choose(table[len(table)-1][j],2) 
     index += choose(table[i][j],2) 


expected_index = (sum_a*sum_b) 
expected_index = expected_index/choose(n,2) 
max_index = (sum_a+sum_b) 
max_index = max_index/2 

return (index - expected_index)/(max_index-expected_index) 


#choose to compute rand 
def choose(n,r): 

f = math.factorial 
if (n-r)>=0: 
    return f(n) // f(r) // f(n-r) 
else: 
    return 0 

vorausgesetzt, ich die Kontingenztafel korrekt erstellt haben, habe ich noch Werte außerhalb des Bereichs erhalten (- 1,1).

Zum Beispiel:

Kreuztabelle:

[1, 0, 0, 0, 0, 0, 0, 1] 
[1, 0, 0, 0, 0, 0, 0, 1] 
[0, 0, 0, 1, 0, 0, 0, 1] 
[0, 1, 0, 0, 0, 0, 0, 1] 
[0, 0, 0, 0, 0, 1, 1, 2] 
[1, 0, 1, 0, 1, 0, 0, 3] 
[0, 0, 0, 0, 0, 0, 1, 1] 
[3, 1, 1, 1, 1, 1, 2, 0] 

ergibt einen ARI von -1.6470588235294115, wenn ich meinen Code ausführen. Gibt es einen Fehler in diesem Code?

Auch hier ist, wie ich die Kontingenz Matrix bin Computing:

table = [[0 for _ in range(len(subjects)+1)]for _ in range(len(subjects)+1)] 
#comparing all clusters 
for i in range(len(clusters)): 
    index_count = 0 
    for subject, orgininsts in orig_clusters.items(): 
     madeinsts = clusters[i].instances 
     intersect_count = 0 
     #comparing all instances between the 2 clusters 
     for orginst in orgininsts: 
      for madeinst in makeinsts: 
       if orginst == madeinst: 
        intersect_count += 1 

     table[index_count][i] = intersect_count 
     index_count += 1 


for i in range(len(table)-1): 
    a = 0 
    b = 0 
    for j in range(len(table)-1): 
     a += table[i][j] 
     b += table[j][i] 

    table[i][len(table)-1] = a 
    table[len(table)-1][i] = b 

clusters ist eine Liste der Cluster-Objekte, die instances Attribut haben, die eine Liste der Instanzen in diesem Cluster enthalten ist. orig_clusters ist ein Dikton mit Schlüsseln, die Cluster-Labels darstellen, und Werte sind eine Liste von Instanzen, die in diesem Cluster enthalten sind. Gibt es einen Fehler in diesem Code?

Antwort

0

Sie machen einige Fehler bei der Berechnung des ARI in Ihrem Code - Sie berechnen a und b zu oft, weil Sie Ihre Tabelle zweimal statt nur einmal durchlaufen.

Auch übergeben Sie n als Parameter, aber anscheinend ist es auf 10 (das ist, wie ich Ihr Ergebnis erhalten). Es wäre einfacher, die Tabelle einfach zu passieren und dann n von dort zu berechnen. Ich reparierte Code ein bisschen:

def ARI(table): 
    index = 0 
    sum_a = 0 
    sum_b = 0 
    n = sum([sum(subrow) for subrow in table]) #all items summed 

    for i in range(len(table)): 
     b_row = 0#this is to hold the col sums 
     for j in range(len(table)): 
      index += choose(table[i][j], 2) 
      b_row += table[j][i] 
     #outside of j-loop b.c. we want to use a=rowsums, b=colsums 
     sum_a += choose(sum(table[i]), 2) 
     sum_b += choose(b_row, 2) 

    expected_index = (sum_a*sum_b) 
    expected_index = expected_index/choose(n,2) 
    max_index = (sum_a+sum_b) 
    max_index = max_index/2 

    return (index - expected_index)/(max_index-expected_index) 

oder wenn Sie passieren auf dem Tisch mit Zeilen- und Spaltensummen:

def ARI(table): 

    index = 0 
    sum_a = 0 
    sum_b = 0 
    n = sum(table[len(table)-1]) + sum([table[i][len(table)-1] for i in range(len(table)-1)]) 
    for i in range(len(table)-1): 
     sum_a += choose(table[i][len(table)-1],2) 
     sum_b += choose(table[len(table)-1][i],2) 
     for j in range(len(table)-1): 
      index += choose(table[i][j],2) 

    expected_index = (sum_a*sum_b) 
    expected_index = expected_index/choose(n,2) 
    max_index = (sum_a+sum_b) 
    max_index = max_index/2 

    return (index - expected_index)/(max_index-expected_index) 

dann

def choose(n,r): 
    f = math.factorial 
    if (n-r)>=0: 
     return f(n) // f(r) // f(n-r) 
    else: 
     return 0 

table = [[1, 0, 0, 0, 0, 0, 0, 1], 
[1, 0, 0, 0, 0, 0, 0, 1], 
[0, 0, 0, 1, 0, 0, 0, 1], 
[0, 1, 0, 0, 0, 0, 0, 1], 
[0, 0, 0, 0, 0, 1, 1, 2], 
[1, 0, 1, 0, 1, 0, 0, 3], 
[0, 0, 0, 0, 0, 0, 1, 1], 
[3, 1, 1, 1, 1, 1, 2, 0]] 

ARI(table) 

ARI(table) 
Out[56]: -0.0604008667388949 

Das richtige Ergebnis!

+0

Danke, nur der Vollständigkeit halber, die letzte Zeile und die Spalte von 'table' sind die Summen der einzelnen Zeilen und Spalten, was ich wirklich machen wollte, ist die ARI auf 'table' zu berechnen. len (table) -1] [len (table) -1] ', und benutze die zwei letzten Spalten, um' sum_a' und 'sum_b' zu berechnen, obwohl du die letzte Spalte und Zeile löschst und dann deine Version von' ARI (Tabelle) funktioniert, und es ist nicht notwendig, die letzte Zeile und Spalte zu erstellen. – tharvey

+0

Oh - das habe ich nicht gesehen. In diesem Fall wiederholst du eine Schleife zu oft für a und b, siehe meine Bearbeitung :) – erocoar