我在 this post 中找到了代码非常有帮助。 (我会对该帖子添加评论,但我需要 50 个声望点。)
我在上面的帖子中使用了相同的代码,但添加了一个我一直用来调试我自己的集群代码的测试文档。由于某种原因,1 个文档中的单词出现在两个集群中。
代码是:
更新:我在下面的文档中添加了“独特的句子”。
documents = ["I ran yesterday.",
"The sun was hot.",
"I ran yesterday in the hot and humid sun.",
"Yesterday the sun was hot.",
"Yesterday I ran in the hot sun.",
"Unique sentence." ]
vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(documents)
#cluster 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 clusters
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
我收到的输出是:
更新:我更新了下面的输出以反射(reflect)上面的“独特的句子”。
集群 0: 太阳 热的 昨天 跑了 湿 独特的 句子 集群 1: 独特的 句子 昨天 太阳 跑了 湿 热
您会注意到,“潮湿”在两个集群中都显示为顶部术语,即使它仅出现在上述文档的第一行中。我希望一个独特的词,如本例中的“潮湿”,仅在其中一个集群中成为顶级术语。
谢谢!
请您参考如下方法:
TF*IDF 告诉您单词(在本例中为列)对特定文档(在本例中为行)的代表性。我所说的代表是指:一个词在一个文档中频繁出现,但在其他文档中不频繁出现。 TF*IDF 值越高,这个词就越能代表一个特定的文档。
现在让我们开始了解您实际使用的值(value)观。从 sklearn 的 kmeans 中,您使用返回变量 cluster_centers。这将为您提供每个聚类的坐标,这是一个 TF*IDF 权重数组,每个单词一个。重要的是要注意,这些只是词频的某种抽象形式,不再与特定文档相关。接下来, numpy.argsort() 为您提供对数组进行排序的索引,从最低 TF*IDF 值的索引开始。所以在那之后你用 [:,::-1] 反转它的顺序。现在你有了开头那个聚类中心最有代表性的词的索引。
现在,让我们多谈谈 k-means。 k-means 随机初始化它的 k-cluster 中心。然后将每个文档分配给一个中心,然后重新计算聚类中心。重复此操作,直到满足最小化文档与其最近中心之间的平方距离之和的优化标准。这对您意味着,由于随机初始化,每个簇维度很可能没有 TF*IDF 值 0。此外,一旦满足优化标准,k-means 就会停止。因此,一个中心的 TF*IDF 值仅意味着分配给其他聚类的文档的 TF*IDF 更接近该中心而不是其他聚类中心。
另外一点是,对于 order_centroids[i, :10],每个集群中最有代表性的 10 个词会被打印出来,但是由于总共只有 5 个词,所以所有的词都会被打印出来无论哪种方式,只是顺序不同。
希望对您有所帮助。顺便说一句,k-means 不能保证您找到全局最优解,并且可能会陷入局部最优解,这就是为什么它通常以不同的随机起点运行多次。
