【问题标题】:How to Matching Labels Cluster with True Labels with K-Means using python如何使用 python 使用 K-Means 匹配具有真实标签的标签集群
【发布时间】:2020-12-05 13:12:32
【问题描述】:

我在使用 Kmeans 算法标记数据时遇到问题。我的测试句子得到了真正的集群,但我没有得到真正的标签。我已经使用 numpy 将集群与 true_label_test 进行匹配,但是这个 kmeans 可以移动集群,真正的标签与集群的数量不匹配。我需要帮助解决这个问题。这是我的代码

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.neighbors import KNeighborsClassifier
from sklearn.cluster import KMeans
from nltk.corpus import stopwords 
from nltk.stem.wordnet import WordNetLemmatizer
import string
import re
import numpy as np
from collections import Counter

stop = set(stopwords.words('indonesian'))
exclude = set(string.punctuation) 
lemma = WordNetLemmatizer()

# Cleaning the text sentences so that punctuation marks, stop words & digits are removed  
def clean(doc):
    stop_free = " ".join([i for i in doc.lower().split() if i not in stop])
    punc_free = ''.join(ch for ch in stop_free if ch not in exclude)
    normalized = " ".join(lemma.lemmatize(word) for word in punc_free.split())
    processed = re.sub(r"\d+","",normalized)
    y = processed.split()
    #print (y)
    return y

path = "coba.txt"

train_clean_sentences = []
fp = open(path,'r')
for line in fp:
    line = line.strip()
    cleaned = clean(line)
    cleaned = ' '.join(cleaned)
    train_clean_sentences.append(cleaned)

#print(train_clean_sentences)
       
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(train_clean_sentences)

# Clustering the training 30 sentences with K-means technique
modelkmeans = KMeans(n_clusters=3, init='k-means++', max_iter=200, n_init=100)
modelkmeans.fit(X)

teks_satu = "Aplikasi Machine Learning untuk mengenali daun mangga dengan metode CNN"

test_clean_sentence = []

cleaned_test = clean(teks_satu)
cleaned = ' '.join(cleaned_test)
cleaned = re.sub(r"\d+","",cleaned)
test_clean_sentence.append(cleaned)
    
Test = vectorizer.transform(test_clean_sentence) 

true_test_labels = ['AI','VR','Sistem Informasi']

predicted_labels_kmeans = modelkmeans.predict(Test)
print(predicted_labels_kmeans)

print ("\n-------------------------------PREDICTIONS BY K-Means--------------------------------------")
print ("\nIndex of Virtual Reality : ",Counter(modelkmeans.labels_[5:10]).most_common(1)[0][0])
print ("Index of Machine Learning : ",Counter(modelkmeans.labels_[0:5]).most_common(1)[0][0]) 
print ("Index of Sistem Informasi : ",Counter(modelkmeans.labels_[10:15]).most_common(1)[0][0])
print ("\n",teks_satu,":",true_test_labels[np.int(predicted_labels_kmeans)],":",predicted_labels_kmeans)

【问题讨论】:

    标签: python numpy flask scikit-learn k-means


    【解决方案1】:

    我遇到了同样的问题:我的集群(kmeans)确实返回了不同的类(集群编号)然后是真正的类。真实标签和预测标签不匹配的结果。对我有用的解决方案是this 代码(滚动到“排列最大化对角元素的总和”)。虽然这种方法很有效,但我认为在某些情况下它是错误的。

    【讨论】:

    【解决方案2】:

    这是一个具体示例,展示了如何将 KMeans 集群 ID 与训练数据标签进行匹配。基本思想是confusion_matrixshall 在其对角线上的值很大,假设分类正确完成。这是将聚类中心 id 与训练标签相关联之前的混淆矩阵:

    cm = 
    array([[  0, 395,   0,   5,   0],
           [  0,   2,   5, 391,   2],
           [  2,   0,   0,   0, 398],
           [  0,   0, 400,   0,   0],
           [398,   0,   0,   0,   2]])
    

    现在我们只需要重新排序混淆矩阵,使其较大的值重新定位在对角线上。它可以很容易地实现

    cm_argmax = cm.argmax(axis=0)
    cm_argmax
    y_pred_ = np.array([cm_argmax[i] for i in y_pred])
    

    这里我们得到了新的混淆矩阵,现在看起来很熟悉,对吧?

    cm_ = 
    array([[395,   5,   0,   0,   0],
           [  2, 391,   2,   5,   0],
           [  0,   0, 398,   0,   2],
           [  0,   0,   0, 400,   0],
           [  0,   0,   2,   0, 398]])
    

    您可以通过accuracy_score进一步验证结果

    y_pred_ = np.array([cm_argmax[i] for i in y_pred])
    accuracy_score(y,y_pred_)
    # 0.991
    

    完整的独立代码在这里:

    import matplotlib.pyplot as plt
    from sklearn.cluster import KMeans
    from sklearn.datasets import make_blobs
    from sklearn.metrics import confusion_matrix,accuracy_score
    blob_centers = np.array(
        [[ 0.2,  2.3],
         [-1.5 ,  2.3],
         [-2.8,  1.8],
         [-2.8,  2.8],
         [-2.8,  1.3]])
    blob_std = np.array([0.4, 0.3, 0.1, 0.1, 0.1])
    X, y = make_blobs(n_samples=2000, centers=blob_centers,
                      cluster_std=blob_std, random_state=7)
    
    def plot_clusters(X, y=None):
        plt.scatter(X[:, 0], X[:, 1], c=y, s=1)
        plt.xlabel("$x_1$", fontsize=14)
        plt.ylabel("$x_2$", fontsize=14, rotation=0)
    
    plt.figure(figsize=(8, 4))
    plot_clusters(X)
    plt.show()
    
    k = 5
    kmeans = KMeans(n_clusters=k, random_state=42)
    y_pred = kmeans.fit_predict(X)
    cm = confusion_matrix(y, y_pred)
    cm
    cm_argmax = cm.argmax(axis=0)
    cm_argmax
    y_pred_ = np.array([cm_argmax[i] for i in y_pred])
    cm_ = confusion_matrix(y, y_pred)
    cm_
    accuracy_score(y,y_pred_)
    

    【讨论】:

      【解决方案3】:

      您可以将每个集群中大多数真实标签的标签分配给该集群

      【讨论】:

      猜你喜欢
      • 2021-01-29
      • 2020-12-14
      • 2012-07-25
      • 2018-12-26
      • 2020-07-10
      • 2021-06-18
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      相关资源
      最近更新 更多