当我们只向它提供单个单词的 tfidf 向量时,kmeans 是如何知道如何对文档进行聚类的?

Posted

技术标签:

【中文标题】当我们只向它提供单个单词的 tfidf 向量时,kmeans 是如何知道如何对文档进行聚类的?【英文标题】:How does kmeans know how to cluster documents when we only feed it tfidf vectors of individual words? 【发布时间】:2015-02-19 13:29:50 【问题描述】:

我正在使用 scikit learn 的 Kmeans 算法对 cme​​ts 进行聚类。

sentence_list=['hello how are you', "I am doing great", "my name is abc"]

vectorizer=TfidfVectorizer(min_df=1, max_df=0.9, stop_words='english', decode_error='ignore')
vectorized=vectorizer.fit_transform(sentence_list)

km=KMeans(n_clusters=num_clusters, init='k-means++',n_init=10, verbose=1)
km.fit(vectorized)

当我打印向量化的输出时,它会给我单词的索引和索引的 tf-idf 分数。

所以我想知道,鉴于我们只获得单词的 tfidf 分数,我们如何设法根据单个单词而不是整个文档的分数来对文档进行聚类?或者它可能会这样做......有人可以向我解释一下这背后的概念吗?

【问题讨论】:

不确定你在问什么。将文本拆分为单词的过程是矢量化/拟合过程的一部分。 我的最终目标是能够绘制一个二维图,其中 y 轴是 tfidf 分数,x 轴可能是计数向量(或其他更有意义的东西),每个数据点都是 1文档。所以我很想知道每个句子的分数是否实际上是在幕后计算的,以便将分数最相似的聚类聚集在一起? 【参考方案1】:

您应该看看Kmeans algorithm 的工作原理。首先,停用词永远不会到达vectorized,因此被 Kmeans 完全忽略,并且对文档的聚类方式没有任何影响。现在假设你有:

sentence_list=["word1", "word2", "word2 word3"]

假设您需要 2 个集群。在这种情况下,您希望第二个和第三个文档在同一个集群中,因为它们共享一个共同的词。让我们看看这是如何发生的。

文档vectorized 的数字表示形式如下:

word1     word3     word2
    1  0.000000  0.000000     # doc 1
    0  1.000000  0.000000     # doc 2
    0  0.605349  0.795961     # doc 3

在 Kmeans 的第一步中,从数据中随机选择一些质心,例如文档 1 和文档 3 将是初始质心:

Centroid 1:     [1, 0.000000, 0.000000]

Centroid 2:     [0, 0.605349, 0.795961]

现在,如果您计算每个点(文档)到两个质心中的每一个的距离,您将看到:

文档 1 到质心 1 的距离为 0,因此它属于质心 1 文档 3 到质心 2 的距离为 0,因此它属于质心 2

最后我们计算剩下的文档 2 到每个质心的距离,找出它属于哪一个:

>>> from scipy.spatial.distance import euclidean

>>> euclidean([0, 1, 0], [1, 0, 0])               # dist(doc2, centroid1)
1.4142135623730951

>>> euclidean([0, 1, 0], [0, 0.605349, 0.795961]) # dist(doc2, centroid2)
0.8884272507056005

所以第二个文档和第二个质心更接近,这意味着第二个文档被分配到第二个质心。

【讨论】:

是否可以在 2d 轴上绘制每个文档以进行可视化表示,从而让我们更好地了解我们应该拥有多少个集群或质心应该在哪里? 我从未在整个文档上这样做过,但我认为您的想法没有问题。我认为应该是可行的。 如果我们现在要预测一个新文档,如何从第二个集群中选择质心,因为它有两个文档(1 和 3)? 结果如何绘制在图表上?对于更高维度的数据。我已经对文档实施了聚类,我想做的是绘制结果。 @elyase【参考方案2】:

TF/IDF 是一种度量,用于计算文档中某个单词相对于该文档中其他单词的重要性。它不计算独立词的重要性。 (这是有道理的,对吧?因为重要性总是意味着对他人的特权!)。所以每个词的TF/IDF其实就是一个文档相对于这个词的重要性度量。

我没有看到您的代码中使用了 TF/IDF。但是,可以使用 TF/IDF 分数作为特征来计算 kmeans 算法。此外,对您提到的三个示例文档进行聚类是根本不可能的,而那里没有两个文档有一个共同的词!

编辑1:首先,如果“猫”这个词出现在两个文档中,它们可能会聚集在一起(取决于两个文档中的其他词以及其他文档) .其次,您应该了解更多关于 k-means 的知识。您会看到,kmeans 使用特征将文档聚集在一起,并且文档中每个单词的每个 tf/idf 分数都是一个特征度量,用于将该文档与语料库中的其他文档进行比较。

【讨论】:

这些只是例子,所以如果在我的句子中的 2 个单词中存在“cat”这个词,那么 2 个带有“cat”的句子是否会基于此聚集在一起,因为其他词是停用词?如果是这种情况,算法是否会根据文档中每个单词的 tfidf 计算每个句子的分数(假设 'cat' 的 tfidf 分数很高)? @jenn 查看我的第一个编辑!如果您还有其他问题,请告诉我。

以上是关于当我们只向它提供单个单词的 tfidf 向量时,kmeans 是如何知道如何对文档进行聚类的?的主要内容,如果未能解决你的问题,请参考以下文章

我们如何使用带有多项朴素贝叶斯的 TFIDF 向量?

我在 k-fold cross_validation 中使用相同的 Tfidf 词汇吗

从 HashingVectorizer 中检索词汇

tfidf w2v给出NaN值。

计算句子相似度的方法

文本挖掘——文本特征TFIDF权重计算及文本向量空间VSM表示