Python матрица путаницы - PullRequest
0 голосов
/ 30 мая 2020

У меня проблема с оценкой результата кластеров.

У меня 3 списка:

# 10 objects in my corpus
TOT = [1,2,3,4,5,6,7,8,9,10]

# .... clustering into k=5 clusters

# For each automatic cluster:

    # Objects with ID 2 and 8 are stored into this
    predicted = [2,8]

    # For each cluster in the ground truth:  
        true = [2,4,9]

        # computes TP, FP, TN, FN
        A = set(docs_in_cluster)
        B = set(constraints)

        TP = list(A & B)
        FP = list(A - (A & B))
        TN = list((TOT - A) & (TOT - B))
        FN = list(B - A)

Мой вопрос: могу ли я вычислить TP, FP, TN, FN для каждого кластер? Есть ли в этом смысл?

РЕДАКТИРОВАТЬ: воспроизводимый код

Краткая история:

Я занимаюсь НЛП, у меня есть корпус документов размером 9k, который Я обработал с помощью Gensim Word2Ve c, извлек векторы и вычислил «вектор документа» для каждого документа. После этого я вычислил косинусное сходство между векторами документа, получив матрицу 9k x 9k.

Наконец, используя эту матрицу, я выполнил KMeans и иерархическую кластеризацию.

Давайте рассмотрим результаты HA C с 14 кластерами:

id    label
 0        1
 1        8
     ....
9k       12

Теперь проблема: как я могу оценить качество моих кластеров? Мой профессор прочитал 100 из этих 9k документов и создал несколько «кластеров», в которых говорится: «Хорошо, в этом документе говорится о: label1» или «Хорошо, это другой разговор о label2 и label3.

Обратите внимание, что ярлыки, предоставленные моим профессором, совершенно не связаны с процессом кластеризации и представляют собой просто сводку топовых c, но число то же самое (в этом примере = 14).

Код

У меня есть два фрейма данных, один выше из кластеризации HA C и один из 100 документов от моих профессоров, который выглядит так: (с примером, сделанным ранее)

GT

id    label1    label2    label3    ....    label14
 5         1         0         0                 0
34         0         1         1                 0
      ...........................

И, наконец, мой код делает это:

 # since I have labels only for 100 of my 9k documents
 indexes = list(map(int, ground_truth['id'].values.tolist()))
 reduced_df = clusters.loc[clusters['id'].isin(indexes), :]

 # now reduced_df contains only the documents that have been read by my prof
 TOT = set(reduced_df['id'].values.tolist())

 for each cluster from HAC
    doc_in_this_cluster = [ .... ]

    for each cluster from GT
       doc_in_this_label = [ ... ]

        A = set(doc_in_this_cluster )
        B = set(doc_in_this_label )

        TP = list(A & B)
        FP = list(A - (A & B))
        TN = list((TOT - A) & (TOT - B))
        FN = list(B - A)

И код:

indexes = list(map(int, self.ground_truth['id'].values.tolist()))
    # reduce clusters_file matching only manually analyzed documents:  -------->   TOT
    reduced_df = self.clusters.loc[self.clusters['id'].isin(indexes), :]

    TOT = set(reduced_df['id'].values.tolist())

    clusters_groups = reduced_df.groupby('label')

    for label, df_group in clusters_groups:
        docs_in_cluster = df_group['id'].values.tolist()

        row = []
        for col in self.ground_truth.columns[1:]:
            constraints = list(
                map(int, self.ground_truth.loc[self.ground_truth[col] == 1, 'id'].values.tolist())
            )

            A = set(docs_in_cluster)
            B = set(constraints)

            TP = list(A & B)
            FP = list(A - (A & B))
            TN = list((TOT - A) & (TOT - B))
            FN = list(B - A)

            print(f"HAC Cluster: {label} - GT Label: {col}")
            print(TP, FP, TN, FN)

1 Ответ

0 голосов
/ 30 мая 2020

Я предполагаю, что вы пытаетесь реализовать операции над наборами. Вы можете попробовать следующие функции, чтобы решить ваш случай:

def setSubtract(A,B):
    C=[]
    for i in A:
        if i in B:
            pass
        else:
            C.append(i)
    return C

def setIntersection(A,B):
    C=[]
    for i in A:
        if i in B:
            C.append(i)
    return C

TOT = [1,2,3,4,5,6,7,8,9,10]
A=[1,2,3,4]
B=[2,3]
print("A&B",setIntersection(A,B))
print("TOT-B",setSubtract(TOT,B))

Вывод:

A&B [2, 3]
TOT-B [1, 4, 5, 6, 7, 8, 9, 10]
...