如何使用k-means(Flann with python)对文档进行聚类?

时间:2012-09-19 14:51:13

标签: nlp cluster-analysis data-mining k-means text-mining

我想根据相似性对文档进行聚类。

我已经尝试过ssdeep(相似性哈希),非常快但我被告知k-means更快,而且flann是所有实现中最快的,而且更准确所以我正在尝试使用python绑定flann但我找不到任何示例如何在文本上执行它(它只支持数组)。

我对这个领域非常陌生(k-means,自然语言处理)。我需要的是速度和准确性。

我的问题是:

  1. 我们可以使用KMeans进行文档相似性分组/聚类(Flann似乎不允许任何文本输入)
  2. Flann是正确的选择吗?如果没有,请建议我支持文本/文档集群的高性能库,它具有python包装器/ API。
  3. k-means是正确的算法?

2 个答案:

答案 0 :(得分:20)

您需要将文档表示为数字数组(也称为矢量)。有很多方法可以做到这一点,具体取决于你想要的复杂程度,但最简单的方法就是将表示作为单词计数的向量。

所以这就是你所做的:

  1. 计算每个单词出现在文档中的次数。

  2. 选择一组将包含在矢量中的“功能”字样。这应该排除非常常见的单词(也称为“停用词”),如“the”,“a”等。

  3. 根据要素词的计数为每个文档制作一个向量。

  4. 这是一个例子。

    如果您的“文档”是单个句子,并且它们看起来像(每行一个文档):

    there is a dog who chased a cat
    someone ate pizza for lunch
    the dog and a cat walk down the street toward another dog
    

    如果我的一组特征词是[dog, cat, street, pizza, lunch],那么我可以将每个文档转换为一个向量:

    [1, 1, 0, 0, 0]  // dog 1 time, cat 1 time
    [0, 0, 0, 1, 1]  // pizza 1 time, lunch 1 time
    [2, 1, 1, 0, 0]  // dog 2 times, cat 1 time, street 1 time
    

    你可以在你的k-means算法中使用这些向量,它有希望将第一个和第三个句子组合在一起,因为它们是相似的,并且使第二个句子成为一个单独的簇,因为它是非常不同的。

答案 1 :(得分:14)

这里有一个大问题:

K-means是为欧几里德距离设计的。

关键问题是平均功能。平均值将减少欧几里德距离的方差,但对于不同的距离函数可能不会这样做。所以在最坏的情况下,k-means将不再收敛,而是在无限循环中运行(尽管大多数实现都支持在最大迭代次数停止)。

此外,对于稀疏数据,均值不是很明智,而文本向量往往非常稀疏。粗略地说,问题在于大量文档的 mean 将不再像真实文档那样,并且这种方式与任何真实文档不同,并且与其他平均向量更相似。所以结果在一定程度上会退化。

对于文本向量,您可能希望使用不同的距离函数,例如余弦相似度。

当然,您首先需要计算数字向量。例如,通过使用相对项频率,通过 TF-IDF 对它们进行标准化。

k-means的概念有一种变体,称为 k-medoids 。它可以使用任意距离函数,并且通过使用对集群最重要的真实文档(“medoid”)来避免整个“均值”的事情。但是已知的算法比k-means慢得多。