Skip to main content
 首页 » 编程设计

python之聚类文本文档并获取重复的顶级术语

2025年05月04日16傻小

我在 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 不能保证您找到全局最优解,并且可能会陷入局部最优解,这就是为什么它通常以不同的随机起点运行多次。