Расчет точности кластера - PullRequest
0 голосов
/ 28 февраля 2019

Я хотел бы написать код Python для расчета точности кластера r следующим образом:

r = (A1+ ... +Ai+ ...Ak) / (the number of data objects)

, где Ai - количество объектов данных, встречающихся в i -й кластер и соответствующий ему истинный кластер.

Мне нужно реализовать его, чтобы сравнить производительность кластеризации с исследовательской работой, которая использует этот критерий точности.
Я искал существующие методыв sklearn, но не смог найти того, кто сделал это, и попытался написать это сам.

Вот код, который я написал:

    # For each label in prediction, extract true labels of the same 
    # index as 'labels'. Then count the number of instances of respective
    # true labels in 'labels', and assume the one with the maximum 
    # number of instances is the corresponding true label.
    pred_to_true_conversion={}
    for p in np.unique(pred):
        labels=true[pred==p]
        unique, counts=np.unique(labels, return_counts=True)
        label_count=dict(zip(unique, counts))
        pred_to_true_conversion[p]=max(label_count, key=label_count.get)

    # count the number of instances whose true label is the same
    # as the converted predicted label.
    count=0
    for t, p in zip(true, pred):
        if t==pred_to_true_conversion[p]: count+=1

    return count/len(true)

Однако я недумаю, что мой подход «перераспределения меток» - это умный способ, и должен быть лучший способ для вычисления r.У моего метода есть проблемы, такие как:

  1. Он основан на предположении, что соответствующая истинная метка является той, которая встречается чаще всего в предсказанном кластере, но это не всегда так.
  2. Различные прогнозируемые метки кластера соотносятся с одной и той же истинной меткой кластера, особенно когда количество классов отличается в истинных метках и прогнозируемых метках.

Как реализовать точность r?Или в существующих библиотеках кластеризации есть способ сделать это?

1 Ответ

0 голосов
/ 28 февраля 2019

Я верю, что вы описываете то, что я тоже хотел сделать некоторое время назад.Вот как я решил это:

from sklearn.metrics.cluster import contingency_matrix
from sklearn.preprocessing import normalize

normalize(contingency_matrix(labels_pred=pred, labels_true=true), norm='l1', axis=1)

Эта матрица дает отзыв для каждой комбинации кластер / метка.

edit:

Проблемы, которые вы заявляете с помощью этого метода, я считаю, ему присущи.По некоторым причинам некоторые статьи предпочитают сообщать точность или показатель F для результатов кластеризации, даже если они не совсем подходят для этого.по крайней мере, решает несколько кластеров сопоставляются с одной проблемой метки истины.Для решения этой конкретной проблемы они используют алгоритм назначения задач.

Это мой код для оценки "Hungarian F1":

from munkres import Munkres
def f_matrix(labels_pred, labels_true):
    # Calculate F1 matrix
    cont_mat = contingency_matrix(labels_pred=labels_pred, labels_true=labels_true)
    precision = normalize(cont_mat, norm='l1', axis=0)
    recall = normalize(cont_mat, norm='l1', axis=1)
    som = precision + recall
    f1 =  np.round(np.divide((2 * recall * precision), som, out=np.zeros_like(som), where=som!=0), 3)
    return f1

def f1_hungarian(f1):
    m = Munkres()
    inverse = 1 - f1
    indices = m.compute(inverse.tolist())
    fscore = sum([f1[i] for i in indices])/len(indices)
    return fscore
f1_hungarian(f_matrix(pred, true))
...