5

Mam zestaw danych o znanych etykietach. Chcę spróbować klastrować i sprawdzić, czy mogę uzyskać te same klastry podane przez znane etykiety. Aby zmierzyć dokładność, potrzebuję czegoś w rodzaju matrycy mylącej.Macierz konwersji dla klastrów w scikit-learn

Wiem, że mogę łatwo uzyskać matrycę do pomylenia dla zestawu testowego problemu klasyfikacji. Próbowałem już tak jak this.

Jednak nie można go używać do tworzenia klastrów, ponieważ oczekuje, że zarówno kolumny, jak i wiersze będą miały ten sam zestaw etykiet, co ma sens w przypadku problemu z klasyfikacją. Ale w przypadku problemu klastrowego oczekuję czegoś takiego.

Wiersze - Rzeczywiste etykiety

Kolumny - Nowe nazwy klastra (tj cluster-1, klaster-2 itd.)

Czy istnieje sposób, aby to zrobić?

Edytuj: Oto więcej szczegółów.

W sklearn.metrics.confusion_matrix, że spodziewa y_test i y_pred mieć te same wartości, a labels być etykiety tych wartości.

Dlatego daje matrycę, która ma takie same etykiety dla obu wierszy i kolumn, jak to.

enter image description here

Ale w moim przypadku (KMeans klastrowania), rzeczywiste wartości są ciągi i szacowane wartości są liczbami (czyli liczba klastrów)

Dlatego, jeśli zadzwonię confusion_matrix(y_true, y_pred) daje poniżej błędu.

ValueError: Mix of label input types (string and number) 

To jest prawdziwy problem. W przypadku problemu klasyfikacji ma to sens. Jednak w przypadku problemu związanego z tworzeniem skupień ograniczenie to nie powinno występować, ponieważ prawdziwe nazwy etykiet i nowe nazwy klastra nie muszą być takie same.

Rozumiem, że próbuję użyć narzędzia, które ma służyć do rozwiązywania problemów związanych z klasyfikacją, w przypadku problemu związanego z tworzeniem klastrów. Moje pytanie brzmi: czy istnieje sposób, w jaki mogę uzyskać taką matrycę dla danych w klastrze.

Mam nadzieję, że pytanie jest teraz jaśniejsze. Daj mi znać, jeśli tak nie jest.

+0

Proszę wyjaśnić to na przykładowej próbce –

+0

Dodano więcej szczegółów. Dzięki. – Bee

+0

Więc jeśli nie wiesz, jak zmapować numer klastra do rzeczywistych wyników, jak będziesz postępować? –

Odpowiedz

0

Sam napisałem kod.

# Compute confusion matrix 
def confusion_matrix(act_labels, pred_labels): 
    uniqueLabels = list(set(act_labels)) 
    clusters = list(set(pred_labels)) 
    cm = [[0 for i in range(len(clusters))] for i in range(len(uniqueLabels))] 
    for i, act_label in enumerate(uniqueLabels): 
     for j, pred_label in enumerate(pred_labels): 
      if act_labels[j] == act_label: 
       cm[i][pred_label] = cm[i][pred_label] + 1 
    return cm 

# Example 
labels=['a','b','c', 
     'a','b','c', 
     'a','b','c', 
     'a','b','c'] 
pred=[ 1,1,2, 
     0,1,2, 
     1,1,1, 
     0,1,2] 
cnf_matrix = confusion_matrix(labels, pred) 
print('\n'.join([''.join(['{:4}'.format(item) for item in row]) 
     for row in cnf_matrix])) 

Edit: (Dayyyuumm) po prostu okazało się, że mogę to zrobić z łatwością Pandas Crosstab: - /.

labels=['a','b','c', 
     'a','b','c', 
     'a','b','c', 
     'a','b','c'] 
pred=[ 1,1,2, 
     0,1,2, 
     1,1,1, 
     0,1,2] 

# Create a DataFrame with labels and varieties as columns: df 
df = pd.DataFrame({'Labels': labels, 'Clusters': pred}) 

# Create crosstab: ct 
ct = pd.crosstab(df['Labels'], df['Clusters']) 

# Display ct 
print(ct) 
+1

Wektoryzuj kod za pomocą numpy, aby był 10 razy szybszy. –

1

Możesz łatwo obliczyć macierz przecięcia parami.

Ale może być konieczne zrobienie tego samemu, jeśli biblioteka sklearn została zoptymalizowana do użycia w klasyfikacji.

+0

Dzięki, po prostu patrzyłem, czy istnieje sposób OOTB, aby to zrobić, zanim sam go zapiszę. – Bee

+1

Oczywiście istnieją takie implementacje. Na przykład na wykresach zwykle masz podobieństwo, a nie odległość. Ale w pewnym momencie łatwiej jest napisać te rzeczy, zamiast siekać za dużo, by skleić ze sobą różne biblioteki, a potem zarazić się wszystkimi ich błędami. –

+0

Zgadzam się, dziękuję. – Bee