Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么余弦距离比在scikitlearn中使用带DBSCAN算法的欧几里德距离慢得多_Python_Scikit Learn - Fatal编程技术网

Python 为什么余弦距离比在scikitlearn中使用带DBSCAN算法的欧几里德距离慢得多

Python 为什么余弦距离比在scikitlearn中使用带DBSCAN算法的欧几里德距离慢得多,python,scikit-learn,Python,Scikit Learn,我将从packagescikit learn中为DBSCAN算法使用两个度量(欧几里德距离和余弦相似性) 问题是,使用欧几里德距离比使用余弦相似性要快得多 守则: // using euclidean distance DBSCAN(eps=0.02, min_samples=5, metric="euclidean").fit(data) // using cosine similarity DBSCAN(eps=0.02, min_samples=5, metric=cosine_

我将从package
scikit learn
中为DBSCAN算法使用两个度量(欧几里德距离和余弦相似性)

问题是,使用欧几里德距离比使用余弦相似性要快得多

守则:

// using euclidean distance    
DBSCAN(eps=0.02, min_samples=5, metric="euclidean").fit(data)

// using cosine similarity
DBSCAN(eps=0.02, min_samples=5, metric=cosine_distance).fit(data)

有人知道余弦相似性导致速度差异的原因吗?

我对scikit学习一无所知,但我可以从数学角度猜出为什么速度会慢一些


定义

假设有两个n维向量(AB

计算结果如下:

Sqrt((A_1 - B_1)^2 + (A_2 - B_2)^2 + ... + (A_N - B_N)^2)
其中
A_m
A中的第
m
个元素。要计算它,需要计算n个差值、n个乘积和1平方根

定义为

cos(x) = A.B / |A||B|
在哪里

因此,
A.B
的n次乘法和2.n次乘法得到
|A
|B


比较

欧几里德距离需要n次减法和n次乘法;余弦相似性需要3.n次乘法

假设减法在计算上是密集型的(几乎可以肯定的是,它的密集度会更低),那么欧几里德的减法是2.n,而余弦的减法是3.n


换句话说,得到余弦差至少比欧几里德距离慢50%。我不知道
scikit-learn
是如何使用这些指标的,也不知道您的n有多大,但这可能是您看到差异的原因。

我对
scikit-learn
一无所知,但我可以从数学角度猜出为什么它可能会慢一些


定义

假设有两个n维向量(AB

计算结果如下:

Sqrt((A_1 - B_1)^2 + (A_2 - B_2)^2 + ... + (A_N - B_N)^2)
其中
A_m
A中的第
m
个元素。要计算它,需要计算n个差值、n个乘积和1平方根

定义为

cos(x) = A.B / |A||B|
在哪里

因此,
A.B
的n次乘法和2.n次乘法得到
|A
|B


比较

欧几里德距离需要n次减法和n次乘法;余弦相似性需要3.n次乘法

假设减法在计算上是密集型的(几乎可以肯定的是,它的密集度会更低),那么欧几里德的减法是2.n,而余弦的减法是3.n


换句话说,得到余弦差至少比欧几里德距离慢50%。我不知道scikit learn如何使用这些指标,也不知道您的n有多大,但这可能是您看到差异的原因。

假设
余弦距离
是一个Python函数:

虽然sklearn允许您指定自定义距离函数,但其性能并不是特别好。对于每一个距离,它都需要在Python解释器中设置一个回调。这自然比内置函数使用的编译本机代码慢得多

Python似乎无法很快解决这一开销。可能需要修改sklearn源代码(添加新的内置代码),或者使用类似Java的东西来实现良好的JIT(例如,ELKI可以通过这种方式扩展,并且对于自定义距离来说速度更快)


Jython听起来很酷(JVM上的Python),但据我所知,它不支持numpy,因此也不支持sklearn。我不知道它是否可以将Python编译成字节码,或者它是否只是一个解释器。

假设
余弦距离
是一个Python函数:

虽然sklearn允许您指定自定义距离函数,但其性能并不是特别好。对于每一个距离,它都需要在Python解释器中设置一个回调。这自然比内置函数使用的编译本机代码慢得多

Python似乎并没有很快解决这种开销。可能需要修改sklearn源代码(添加新的内置代码),或者使用类似Java的东西来实现良好的JIT(例如,ELKI可以通过这种方式扩展,并且对于自定义距离来说速度更快)


Jython听起来很酷(JVM上的Python),但据我所知,它不支持numpy,因此也不支持sklearn。我不知道它是否能将Python编译成字节码,或者它只是一个解释器。

函数cosine_距离是sklearn.metrics.pairwise的距离吗?这就是所谓的余弦距离,不是吗?函数余弦距离是来自sklearn.metrics.pairwise的吗?这就是所谓的余弦距离,不是吗?这很好&对一个例子来说是正确的,但大多数用例都是在一个对象和多个其他对象之间找到的,或者是重复的。在这种情况下,每个向量的范数可以与向量本身一起存储,因此可以为每个迭代保存每个向量的范数。在欧几里得距离中,您将无法添加此优化,因为整个计算都基于两个向量。这很好&正确,对于单个示例也是正确的,但大多数用例都是在一个对象和多个其他对象之间查找,或者重复。在这种情况下,每个向量的范数可以与向量本身一起存储,因此可以为每个迭代保存每个向量的范数。在欧几里得距离中,您将无法添加此优化,因为整个计算都基于两个向量