我试图在大约5000条记录的列表中找到重复项。每条记录都是一个人的姓名和地址,但所有记录都不一致地输入到一个字段中,所以我正在尝试一种模糊匹配方法。我的方法(使用rapidminer)是对文本进行一些预处理(即标记化,删除常见和不相关的单词,如“Mr”等),生成TF-IDF并使用DBSCAN来聚类匹配记录。这可以工作,并且提供了相当不错的结果,但是当我尝试运行完整数据集时需要很长时间。它也导致很多集群只有一个元素,我不知道这会如何影响DBSCAN的计算时间。
是否存在可以更快地处理此类数据的聚类算法,还是有更好的方法来解决此问题?
答案 0 :(得分:3)
您确定群集是最佳方法吗?
对我而言,这听起来好像是在进行近似重复检测,即您定义了一些阈值,只想查找此相似度阈值内是否还有其他对象。 如果您正在使用具有较低minPts值的DBSCAN(例如,minPts = 2),那么您实际上并不是在进行DBSCAN。
如果DBSCAN生成单元素群集,则实现不正确。 DBSCAN中不能有单个元素簇;这些都是噪音对象,应该这样对待。
我不知道RapidMiner中DBSCAN的质量。 如果它基于Weka代码,那就是垃圾(即不要去尝试Weka!)。而且真的很慢。它至少拼写错误:DBScan不正确,它是一个缩写,应拼写为DBSCAN ......
天真实施的DBSCAN具有复杂性O(n^2)
。如果您有一个很好的索引来支持查询,它可以在O(n log n)
中运行。如果你有一个非常糟糕的实现,它可能会下降到O(n^3)
,因为数据结构效率低......(从快速检查来看,quickminer应该在O(n^2)
,但可能会浪费大量的内存到期使用LinkedList<Integer>
,垃圾收集器可能会花费相当多的钱)
实际上5000个对象并没有那么多。因此,问题可能不是聚类算法的复杂性(我在使用ELKI的单个CPU上在60秒内在100000个对象上运行DBSCAN),但距离计算。从快速浏览器快速浏览一下,我无法看到它是否支持稀疏矢量,稀疏矢量上的有效余弦相似性,甚至是预先计算矢量长度以完全利用矢量稀疏性的技巧(以预处理每个对象和存储为代价)额外的双倍)。很明显,如果你的矢量稀疏度为1%与文本向量相同,那么使用低效的非稀疏距离计算将需要大约100倍的时间,计算大量的0。
我刚刚在类似文本的数据集上使用ELKI运行DBSCAN。它没有你的那么大:只有3333个观测值和50个维度,并且稀疏度为13%)。运行DBSCAN需要7秒,epsilon = 0.001,minpts = 3和余弦相似度;没有启用索引加速。所以很明显,问题不在于DBSCAN,而在于RapidMiner的实现。请注意,ELKI与稀疏数据一起使用有点棘手。您需要以正确的输入格式获取数据,设置一些正确的过滤器等。 - 我现在不建议初学者使用它。这更像是为了强调它可能是RapidMiner的相似性函数实现会杀死你的运行时。
我不想劝阻你离开DBSCAN。从聚类的角度来看,它是你能找到的最合适的算法之一:它支持任意距离函数(k-means不支持),你不需要预先知道聚类的数量(你显然不是't)并且它也会选择从群集中删除所有东西(显然你有很多非群集对象)。
但是,我相信你不想要集群 。您似乎对重复检测感兴趣,并且我认为您可以获得更好的性能和结果质量,例如:将文档加载到文本搜索引擎(如Lucene或Xapian),并查询专用文本搜索引擎,以查看是否有近似重复项。 而这些文本搜索引擎真的很擅长:匹配文本。我比苦读者好多了。
答案 1 :(得分:1)
您的问题不是群集,而是 approximate string matching 。
您可能需要查看 Levenshtein Edit Distances 或使用several existing个选项之一。