我正在寻找一种有效的方法,根据相似单词序列的外观将大约1000万个字符串聚类成簇。
考虑一个字符串列表,如:
the fruit hut number one
the ice cre am shop number one
jim's taco
ice cream shop in the corner
the ice cream shop
the fruit hut
jim's taco outlet number one
jim's t aco in the corner
the fruit hut in the corner
算法运行后,我希望它们按如下方式聚类:
the ice cre am shop number one
ice cream shop in the corner
the ice cream shop
jim's taco
jim's taco outlet number one
jim's t aco in the corner
the fruit hut
fruit hut number one
the fruit hut in the corner
很明显,区分聚类的序列是:
ice cream shop, jim's taco and fruit hut
答案 0 :(得分:6)
我认为您正在寻找近似重复检测,您将使用一些未知阈值来聚类,不仅仅是“接近重复” - 而且还有相似的文档。
其中一个已知的解决方案是使用 Jaccard-Similarity 来获取两个文档之间的差异。
Jaccard基本相似 - 从每个文档中获取单词集,让这些集合为s1
和s2
- 并且jaccard相似度为|s1 [intersection] s2|/|s1 [union] s2|
。
通常在面临重复时 - 但是单词的顺序有一些重要性。为了处理它 - 在生成集s1
和s2
时 - 你实际上生成了k-shinglings(或k-gram)集合,而不是单词集合。
在您的示例中,使用k=2
,集合将为:
角落里的冰淇淋店
s2 = { the ice, ice cre, cre am, am shop, shop number, number one }
s4 = {ice cream, cream shop, shop in, in the, the corner }
s5 = { the ice, ice cream, cream shop }
s4 [union] s5 = { ice cream, cream shop, shop in, in the, the corner, the ice }
s4 [intersection] s5 = { ice cream, cream shop }
在上文中,jaccard相似性将为2/6
。
在你的情况下,普通的k-shinglings可能比使用单个单词(1-shingling)表现更差,但你必须测试这些方法。
这个过程可以很好地扩展,以便非常有效地处理大型集合,而无需检查所有对并创建大量集合。更多细节可以在these lecture notes中找到(我在2年前根据作者的笔记给了这个讲座。)
完成此过程后,您基本上有一个度量d(s1,s2)
来衡量每两个句子之间的距离,您可以使用任何已知的clustering算法对它们进行聚类。
免责声明:在实现了近似重复之后,使用this thread的答案作为基础。
答案 1 :(得分:2)
群集是错误的工具。
对于任何无监督算法,以下分区都一样好:
the fruit hut number one
the ice cre am shop number one
jim's taco outlet number one
the ice cream shop
the fruit hut
jim's taco
ice cream shop in the corner
jim's t aco in the corner
the fruit hut in the corner
因为聚类算法"第一"和#34;在拐角处"也是共享短语。第二组是剩菜。
使用监督的代替。