Python:使用Levenshtein距离作为度量标准,使用scikit-learn的dbscan进行字符串聚类:

时间:2016-08-02 12:20:55

标签: python machine-learning scikit-learn cluster-analysis levenshtein-distance

我一直在尝试聚集多个URL数据集(每个约100万个),以查找每个URL的原始和拼写错误。我决定使用levenshtein距离作为相似性度量,并将dbscan作为聚类算法,因为k-means算法不起作用,因为我不知道聚类的数量。

我在使用Scikit-learn实现dbscan时遇到了一些问题。

下面的代码片段适用于我使用的格式的小型数据集,但由于它预先计算了整个距离矩阵,因此占用O(n ^ 2)空间和时间对于我的大型数据集来说太过分了。我已经运行了好几个小时,但它最终只占用了我的电脑的所有内存。

lev_similarity = -1*np.array([[distance.levenshtein(w1[0],w2[0]) for w1 in words] for w2 in words])
dbscan = sklearn.cluster.DBSCAN(eps = 7, min_samples = 1)
dbscan.fit(lev_similarity)

所以我认为我需要一些方法来动态计算相似性,因此尝试了这种方法。

dbscan = sklearn.cluster.DBSCAN(eps = 7, min_samples = 1, metric = distance.levenshtein)
dbscan.fit(words)

但是这种方法最终给我一个错误:

ValueError: could not convert string to float: URL

我意识到这意味着它试图将输入转换为相似函数浮动。但我不希望它这样做。 据我所知,它只需要一个可以接受两个参数并返回一个浮点值的函数,然后它可以与mp进行比较,这是levenshtein距离应该做的。

我在这一点上陷入困​​境,因为我不知道sklearn的dbscan的实现细节,以找出它为什么试图将其转换为float,而且我对如何避免O(n ^)也没有更好的想法2)矩阵计算。

如果有更好或更快的方法来聚集这些我可能忽略的字符串,请告诉我。

2 个答案:

答案 0 :(得分:8)

从scikit-learn faq,您可以通过making a custom metric

执行此操作
self.GrowTextArea = function (data, event) {
    $('#' + event.target.id).height(0).height(event.target.scrollHeight);
}

答案 1 :(得分:3)

尝试使用ELKI代替sklearn。

这是我所知道的唯一允许使用任何指标加速DBSCAN的工具。

它包括Levenshtein距离。您需要使用-db.index向数据库添加索引。我总是使用封面树索引(你需要为索引和算法选择相同的距离!)

你可以在sklearn中使用“pyfunc”距离和球树,但由于翻译,性能非常糟糕。此外,sklearn中的DBSCAN内存密集程度更高。