理解和应用 k-means 聚类进行主题建模
Posted
技术标签:
【中文标题】理解和应用 k-means 聚类进行主题建模【英文标题】:Understanding and applying k-means clustering for topic modeling 【发布时间】:2018-11-22 10:40:40 【问题描述】:我从https://pythonprogramminglanguage.com/kmeans-text-clustering/ 找到了以下关于文档聚类的代码。虽然我从整体上理解了 k-means 算法,但对于每个集群的***术语代表什么以及如何计算它,我有点难以理解?它是集群中出现频率最高的词吗?我读过的一篇博文说,最后输出的单词代表“最接近集群质心的前 n 个单词”(但实际单词“最接近”集群质心意味着什么)。我真的很想了解正在发生的事情的细节和细微差别。谢谢!
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.metrics import adjusted_rand_score
documents = ["This little kitty came to play when I was eating at a restaurant.",
"Merley has the best squooshy kitten belly.",
"Google Translate app is incredible.",
"If you open 100 tab in google you get a smiley face.",
"Best cat photo I've ever taken.",
"Climbing ninja cat.",
"Impressed with google map feedback.",
"Key promoter extension for Google Chrome."]
vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(documents)
true_k = 2
model = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)
model.fit(X)
print("Top terms per cluster:")
order_centroids = model.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names()
for i in range(true_k):
print("Cluster %d:" % i),
for ind in order_centroids[i, :10]:
print(' %s' % terms[ind]),
print
【问题讨论】:
【参考方案1】:在这种情况下,'Top' 与将文本转换为数值数组的方式直接相关。通过使用 TFIDF,您可以根据每个单词在该文档中的流行程度为每个单词分配一个分数,这与整个文档集的流行程度相反。文档中得分高的词表明它比其他词更重要或更能代表该文档。
因此,对于每个集群而言,这一代最热门的词是平均而言在该集群的文档中最重要的词。
这里完成的方式有效且有效,但我发现自己很难理解,我认为这不是特别直观,因为很难理解为什么,如果cluster_centers_
是坐标质心,然后具有最高坐标数的特征是最上面的词。我有点明白但不完全明白(如果有人想解释这是如何工作的,那就太好了!)。
我使用不同的方法来查找集群的最热门术语,我觉得这种方法更直观。我刚刚在包含 250 个文档的语料库上测试了您自己发布的方法,并且最上面的单词完全相同。我的方法的价值在于它可以工作,但是只要您可以提供集群分配列表(任何集群算法都应该提供),您就可以对文档进行集群,这意味着您不依赖于 cluster_centers_
属性的存在.我认为它也更直观。
import numpy as np
def term_scorer(doc_term_matrix, feature_name_list, labels=None, target=None, n_top_words=10):
if target is not None:
filter_bool = np.array(labels) == target
doc_term_matrix = doc_term_matrix[filter_bool]
term_scores = np.sum(doc_term_matrix,axis=0)
top_term_indices = np.argsort(term_scores)[::-1]
return [feature_name_list[term_idx] for term_idx in top_term_indices[:n_top_words]]
term_scorer(X, terms, labels=model.labels_, target=1, n_top_words=10)
model.labels_
属性为您提供每个文档的集群分配列表。在这个例子中,我想找到集群 1 的最高词,所以我分配 target=1
,该函数过滤 X
数组,只保留分配给集群 1 的行。然后它按行对文档中的所有分数求和,所以它有单行,每个单词有一列。然后它使用argsort
将该行按最高值到最低值排序,将这些值替换为单词的原始索引位置。最后,它使用列表推导从最高分获取索引号到n_top_words
,然后通过在feature_name_list
中查找这些索引来构建单词列表。
【讨论】:
【参考方案2】:当单词被转换为向量时,我们将单词的接近度称为它们的相似程度。因此,例如,您可以使用余弦相似度来确定两个词彼此之间的接近程度。 “dog”和“puppy”的向量将相似,因此您可以说这两个词彼此接近。 换句话说,接近度也由上下文词决定。因此,根据句子,单词对 (the, cat) 可以很接近。这就是 word2vec 或类似算法创建词向量的方式。
【讨论】:
我的问题必须更多地处理质心,特别是在文档聚类中,代表什么?如果我输出最热门的术语,“top”是什么意思(最具代表性、最频繁)?以上是关于理解和应用 k-means 聚类进行主题建模的主要内容,如果未能解决你的问题,请参考以下文章