【发布时间】:2020-08-12 20:46:38
【问题描述】:
我注意到scipy 和sklearn 都具有余弦相似度/余弦距离函数。我想测试每个向量对的速度:
setup1 = "import numpy as np; arrs1 = [np.random.rand(400) for _ in range(60)];arrs2 = [np.random.rand(400) for _ in range(60)]"
setup2 = "import numpy as np; arrs1 = [np.random.rand(400) for _ in range(60)];arrs2 = [np.random.rand(400) for _ in range(60)]"
import1 = "from sklearn.metrics.pairwise import cosine_similarity"
stmt1 = "[float(cosine_similarity(arr1.reshape(1,-1), arr2.reshape(1,-1))) for arr1, arr2 in zip(arrs1, arrs2)]"
import2 = "from scipy.spatial.distance import cosine"
stmt2 = "[float(1 - cosine(arr1, arr2)) for arr1, arr2 in zip(arrs1, arrs2)]"
import timeit
print("sklearn: ", timeit.timeit(stmt1, setup=import1 + ";" + setup1, number=1000))
print("scipy: ", timeit.timeit(stmt2, setup=import2 + ";" + setup2, number=1000))
sklearn: 11.072769448000145
scipy: 1.9755544730005568
sklearn 的运行速度几乎比scipy 慢 10 倍(即使您删除了 sklearn 示例的数组 reshape 并生成了已经处于正确形状的数据)。为什么一个明显比另一个慢?
【问题讨论】:
-
我不熟悉
sklearn或scipy的内部工作;但是,除了您在一个实验中而不是在另一个实验中重塑数组这一事实之外,我认为这不是一个公平的比较,因为cosine_similarity计算两个输入数组中所有样本的成对余弦距离(尽管您正在对一个样本的数组调用它),但scipy中的cosine函数仅适用于一维数组,因此可能有更有效的实现。 -
@today 即使您摆脱了数组整形(使用
np.random.rand(1, 400)而不是np.random.rand(400)创建数组以防止整形),sklearn 仍然较慢。我怀疑 sklearn 是为二维数组设计的这一事实可能与它有关,但性能差异仍然很大。
标签: python scikit-learn scipy cosine-similarity