如何使用 python 使用 K-Means 匹配具有真实标签的标签集群
Posted
技术标签:
【中文标题】如何使用 python 使用 K-Means 匹配具有真实标签的标签集群【英文标题】:How to Matching Labels Cluster with True Labels with K-Means using python 【发布时间】: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)
【问题讨论】:
【参考方案1】:我遇到了同样的问题:我的集群(kmeans)确实返回了不同的类(集群编号)然后是真正的类。真实标签和预测标签不匹配的结果。对我有用的解决方案是this 代码(滚动到“排列最大化对角元素的总和”)。虽然这种方法很有效,但我认为在某些情况下它是错误的。
【讨论】:
请在您的答案中添加更多详细信息。请查看***.com/help/how-to-answer 以开始使用。【参考方案2】:这是一个具体示例,展示了如何将 KMeans
集群 ID 与训练数据标签进行匹配。基本思想是confusion_matrix
shall 在其对角线上的值很大,假设分类正确完成。这是将聚类中心 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】:您可以将每个集群中大多数真实标签的标签分配给该集群
【讨论】:
这并没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review以上是关于如何使用 python 使用 K-Means 匹配具有真实标签的标签集群的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Python 中使用 K-Means 聚类找到最佳的聚类数量