我想根据相似性对文档进行聚类。
我已经尝试过ssdeep(相似性哈希),非常快但我被告知k-means更快,而且flann是所有实现中最快的,而且更准确所以我正在尝试使用python绑定flann但我找不到任何示例如何在文本上执行它(它只支持数组)。
我对这个领域非常陌生(k-means,自然语言处理)。我需要的是速度和准确性。
我的问题是:
答案 0 :(得分:20)
您需要将文档表示为数字数组(也称为矢量)。有很多方法可以做到这一点,具体取决于你想要的复杂程度,但最简单的方法就是将表示作为单词计数的向量。
所以这就是你所做的:
计算每个单词出现在文档中的次数。
选择一组将包含在矢量中的“功能”字样。这应该排除非常常见的单词(也称为“停用词”),如“the”,“a”等。
根据要素词的计数为每个文档制作一个向量。
这是一个例子。
如果您的“文档”是单个句子,并且它们看起来像(每行一个文档):
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慢得多。