Kmean 集群中的顶级术语
Kmean clustering top terms in cluster
我正在使用 python Kmean 聚类算法来聚类文档。我创建了一个术语文档矩阵
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
vectorizer = TfidfVectorizer(tokenizer=tokenize, encoding='latin-1',
stop_words='english')
X = vectorizer.fit_transform(token_dict.values())
然后我使用以下代码应用了 Kmean 聚类
km = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)
y=km.fit(X)
我的下一个任务是查看每个集群中的顶级术语,在 googole 上搜索表明许多人使用 km.cluster_centers_.argsort()[:, ::-1] 来查找顶级术语在集群中使用以下代码:
print("Top terms per cluster:")
order_centroids = km.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names()
for i in range(true_k):
print("Cluster %d:" % i, end='')
for ind in order_centroids[i, :10]:
print(' %s' % terms[ind], end='')
print()
现在我的问题是,根据我的理解,km.cluster_centers_ return 是集群中心的坐标,例如,如果有 100 个特征和三个集群,它将 return我们用一个 3 行 100 列的矩阵表示每个簇的质心。我希望了解在上面的代码中如何使用它来确定集群中的顶级术语。
谢谢 任何评论表示赞赏
纳迪姆
关于聚类中心的形状和含义,您是正确的。因为您使用的是 Tf-Idf 向量化器,所以您的 "features" 是给定文档中的单词(每个文档都是它自己的向量)。因此,当您对文档向量进行聚类时,质心的每个 "feature" 代表该词与其的相关性。 "word"(在词汇表中)="feature"(在你的向量中space)="column"(在你的质心矩阵中)
get_feature_names
调用获取列索引到它所代表的词的映射(从文档看来是这样……如果这不能按预期工作,只需反转 vocabulary_
矩阵以获得相同的结果)。
然后 .argsort()[:, ::-1]
行将每个质心转换为其中最 "relevant"(高价值)的列的排序(降序)列表,因此最相关的词(因为 words=列)。
其余代码只是打印,我相信不需要任何解释。所有代码真正做的是按照其中最有价值的 features/words 的降序对每个质心进行排序,然后将这些列映射回它们的原始单词并打印它们。
有点晚了,我也有同样的问题,但找不到满意的答案。
这是我所做的:
from sklearn.cluster import MiniBatchKMeans
from sklearn.feature_extraction.text import TfidfVectorizer
# documents you are clustering
docs = ['first document', 'second', 'third doc', 'etc.'] * 10
# init vectorizer
tfidf = TfidfVectorizer()
# fit vectorizer and get vecs
vecs = tfidf.fit_transform(docs)
# fit your kmeans cluster to vecs
# don't worry about the hyperparameters
clusters = MiniBatchKMeans(
n_clusters=16,
init_size=1024,
batch_size=2048,
random_state=20
).fit_predict(vecs)
# get dict of {keyword id: keyword name}
labels = tfidf.get_feature_names()
def get_cluster_keywords(vecs, clusters, labels, top_n=10):
# init a dict where we will count term occurence
cluster_keyword_ids = {cluster_id: {} for cluster_id in set(clusters)}
# loop through the vector and cluster of each doc
for vec, cluster_id in zip(vecs, clusters):
# inspect non zero elements of rows of sparse matrix
for j in vec.nonzero()[1]:
# check we have seen this keword in this cluster before
if j not in cluster_keyword_ids[cluster_id]:
cluster_keyword_ids[cluster_id][j] = 0
# add a count
cluster_keyword_ids[cluster_id][j] += 1
# cluster_keyword_ids contains ids
# we need to map back to keywords
# do this with the labels param
return {
cluster_id: [
labels[keyword_id] # map from kw id to keyword
# sort through our keyword_id_counts
# only return the top n per cluster
for keyword_id, count in sorted(
keyword_id_counts.items(),
key=lambda x: x[1], # sort from highest count to lowest
reverse=True
)[:top_n]
] for cluster_id, keyword_id_counts in cluster_keyword_ids.items()
}
那么你可以运行:
>>> get_cluster_keywords(vecs, clusters, labels, top_n=10)
{0: ['document', 'first'], 1: ['second'], 2: ['doc', 'third'], 3: ['etc']}
我正在使用 python Kmean 聚类算法来聚类文档。我创建了一个术语文档矩阵
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
vectorizer = TfidfVectorizer(tokenizer=tokenize, encoding='latin-1',
stop_words='english')
X = vectorizer.fit_transform(token_dict.values())
然后我使用以下代码应用了 Kmean 聚类
km = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)
y=km.fit(X)
我的下一个任务是查看每个集群中的顶级术语,在 googole 上搜索表明许多人使用 km.cluster_centers_.argsort()[:, ::-1] 来查找顶级术语在集群中使用以下代码:
print("Top terms per cluster:")
order_centroids = km.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names()
for i in range(true_k):
print("Cluster %d:" % i, end='')
for ind in order_centroids[i, :10]:
print(' %s' % terms[ind], end='')
print()
现在我的问题是,根据我的理解,km.cluster_centers_ return 是集群中心的坐标,例如,如果有 100 个特征和三个集群,它将 return我们用一个 3 行 100 列的矩阵表示每个簇的质心。我希望了解在上面的代码中如何使用它来确定集群中的顶级术语。 谢谢 任何评论表示赞赏 纳迪姆
关于聚类中心的形状和含义,您是正确的。因为您使用的是 Tf-Idf 向量化器,所以您的 "features" 是给定文档中的单词(每个文档都是它自己的向量)。因此,当您对文档向量进行聚类时,质心的每个 "feature" 代表该词与其的相关性。 "word"(在词汇表中)="feature"(在你的向量中space)="column"(在你的质心矩阵中)
get_feature_names
调用获取列索引到它所代表的词的映射(从文档看来是这样……如果这不能按预期工作,只需反转 vocabulary_
矩阵以获得相同的结果)。
然后 .argsort()[:, ::-1]
行将每个质心转换为其中最 "relevant"(高价值)的列的排序(降序)列表,因此最相关的词(因为 words=列)。
其余代码只是打印,我相信不需要任何解释。所有代码真正做的是按照其中最有价值的 features/words 的降序对每个质心进行排序,然后将这些列映射回它们的原始单词并打印它们。
有点晚了,我也有同样的问题,但找不到满意的答案。
这是我所做的:
from sklearn.cluster import MiniBatchKMeans
from sklearn.feature_extraction.text import TfidfVectorizer
# documents you are clustering
docs = ['first document', 'second', 'third doc', 'etc.'] * 10
# init vectorizer
tfidf = TfidfVectorizer()
# fit vectorizer and get vecs
vecs = tfidf.fit_transform(docs)
# fit your kmeans cluster to vecs
# don't worry about the hyperparameters
clusters = MiniBatchKMeans(
n_clusters=16,
init_size=1024,
batch_size=2048,
random_state=20
).fit_predict(vecs)
# get dict of {keyword id: keyword name}
labels = tfidf.get_feature_names()
def get_cluster_keywords(vecs, clusters, labels, top_n=10):
# init a dict where we will count term occurence
cluster_keyword_ids = {cluster_id: {} for cluster_id in set(clusters)}
# loop through the vector and cluster of each doc
for vec, cluster_id in zip(vecs, clusters):
# inspect non zero elements of rows of sparse matrix
for j in vec.nonzero()[1]:
# check we have seen this keword in this cluster before
if j not in cluster_keyword_ids[cluster_id]:
cluster_keyword_ids[cluster_id][j] = 0
# add a count
cluster_keyword_ids[cluster_id][j] += 1
# cluster_keyword_ids contains ids
# we need to map back to keywords
# do this with the labels param
return {
cluster_id: [
labels[keyword_id] # map from kw id to keyword
# sort through our keyword_id_counts
# only return the top n per cluster
for keyword_id, count in sorted(
keyword_id_counts.items(),
key=lambda x: x[1], # sort from highest count to lowest
reverse=True
)[:top_n]
] for cluster_id, keyword_id_counts in cluster_keyword_ids.items()
}
那么你可以运行:
>>> get_cluster_keywords(vecs, clusters, labels, top_n=10)
{0: ['document', 'first'], 1: ['second'], 2: ['doc', 'third'], 3: ['etc']}