Python:使用 scikit-learn 的 dbscan 进行字符串聚类,使用 Levenshtein 距离作为度量:
Posted
技术标签:
【中文标题】Python:使用 scikit-learn 的 dbscan 进行字符串聚类,使用 Levenshtein 距离作为度量:【英文标题】:Python: String clustering with scikit-learn's dbscan, using Levenshtein distance as metric: 【发布时间】:2016-12-07 19:10:51 【问题描述】:我一直在尝试对多个 URL 数据集(每个大约 100 万个)进行聚类,以查找每个 URL 的原始内容和拼写错误。我决定使用 levenshtein 距离作为相似度度量,同时使用 dbscan 作为聚类算法,因为 k-means 算法不起作用,因为我不知道聚类的数量。
我在使用 Scikit-learn 的 dbscan 实现时遇到了一些问题。
下面的这个 sn-p 适用于我使用的格式的小型数据集,但由于它是预先计算整个距离矩阵,因此需要 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
我意识到这意味着它试图将相似函数的输入转换为浮点数。但我不希望它那样做。 据我了解,它只需要一个可以接受两个参数并返回一个浮点值的函数,然后它可以与 eps 进行比较,这是 levenshtein 距离应该做的。
我被困在这一点上,因为我不知道 sklearn 的 dbscan 的实现细节来找出它为什么试图将它转换为浮点数,我也没有更好的想法来避免 O(n^ 2)矩阵计算。
请告诉我是否有更好或更快的方法来聚集我可能忽略的许多字符串。
【问题讨论】:
【参考方案1】:尝试使用 ELKI 而不是 sklearn。
这是我所知道的唯一一个允许使用 any 指标的索引加速 DBSCAN 的工具。
它包括 Levenshtein 距离。您需要使用-db.index
向数据库添加索引。我总是使用覆盖树索引(当然,您需要为索引和算法选择相同的距离!)
您可以在 sklearn 中使用“pyfunc”距离和球树,但由于解释器的原因,性能真的很差。此外,sklearn 中的 DBSCAN 占用更多内存。
【讨论】:
我尝试了 ELKI,但我卡在了它的输入格式上。我在它的网站上找不到太多信息。如果您能指出我正确的方向或提供有关 ELKI dbscan 的完整端到端教程的链接,那就太好了。谢谢。 有多个解析器。使用 JavaDoc,那里解释了输入格式。【参考方案2】:在 scikit-learn 常见问题解答中,您可以通过 making a custom metric 进行此操作:
from leven import levenshtein
import numpy as np
from sklearn.cluster import dbscan
data = ["ACCTCCTAGAAG", "ACCTACTAGAAGTT", "GAATATTAGGCCGA"]
def lev_metric(x, y):
i, j = int(x[0]), int(y[0]) # extract indices
return levenshtein(data[i], data[j])
X = np.arange(len(data)).reshape(-1, 1)
dbscan(X, metric=lev_metric, eps=5, min_samples=2)
【讨论】:
dbscan 方法调用返回什么?更具体地说,我在 Python shell 中运行了这个 sn-p 并得到了一个数组元组 (array([0, 1]), array([ 0, 0, -1])) 我想知道这代表什么。以上是关于Python:使用 scikit-learn 的 dbscan 进行字符串聚类,使用 Levenshtein 距离作为度量:的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Python (scikit-learn) 计算 FactorAnalysis 分数?
将 PMML 模型导入 Python (Scikit-learn)
python机器学习——使用scikit-learn训练感知机模型
在 scikit-learn 中使用 python 生成器 [关闭]