对文本文档进行聚类并获得重复的顶级术语

时间:2016-08-29 15:24:40

标签: python scikit-learn cluster-analysis k-means

我发现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

我收到的输出是:

更新:我更新了下面的输出,以反映上面的“唯一句子”。

群集0:  太阳  热  昨天  跑  湿  独特  句子 群集1:  独特  句子  昨天  太阳  跑  湿  热

你会注意到,“潮湿”在两个群集中都显示为顶级术语,即使它仅在上述文档的一行中。我希望在这种情况下,一个独特的词,如“潮湿”,只是其中一个群集中的顶级词汇。

谢谢!

3 个答案:

答案 0 :(得分:4)

TF * IDF告诉您特定文档(在本例中为行)的单词(在本例中为列)的代表性。代表我的意思是:一个单词经常出现在一个文档中,但在其他文档中并不常见。 TF * IDF值越高,该单词代表特定文档的次数越多。

现在让我们开始了解您实际使用的值。从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并不能保证你找到全局最优并且可能会陷入局部最优,这就是为什么它通常用不同的随机起点多次运行。

答案 1 :(得分:1)

不一定。你正在使用的代码创建了你的语料库中的词袋(不包括停用词)的向量空间(我忽略了tf-idf加权。)。查看您的文档,您的向量空间大小为5,单词数组就像(忽略顺序):

word_vec_space = [yesterday, ran, sun, hot, humid]

为每个文档分配一个数字向量,其中是否包含' word_vec_space'中的单词。

"I ran yesterday." -> [1,1,0,0,0]
"The sun was hot." -> [0,0,1,1,0]
...

执行k均值聚类时,您可以在向量空间中选择k个起始点,并允许这些点移动以优化聚类。最后,两个聚类质心都包含'humid'的非零值。这是因为包含'humid'的一个句子也有'sun''hot''yesterday'

答案 2 :(得分:1)

为什么群集有不同的顶级术语?

考虑到聚类工作(通常不会 - 小心),你会认为这些聚类是坏还是好:

  • 香蕉果实
  • apple fruit
  • apple computer
  • windows computer
  • 窗帘

如果我能得到这样的集群,我会很高兴(因为我会相信我看到了一个错误,因为这些太过于神的结果。文本聚类总是与非工作无关)。

对于文字群集,词汇组合很多,而不仅仅是单词。苹果水果和苹果电脑不一样。