我注意到 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 示例中的数组重塑并生成已处于正确形状的数据)。为什么一个明显比另一个慢?
sklearn
或scipy
的内部工作原理。然而,除了你在一个实验中重塑数组而在另一个实验中没有这个事实之外,我认为这并不是一个公平的比较。因为cosine_similarity
计算两个输入数组中所有样本的余弦距离(虽然你在一个样本的数组上调用它),但scipy
中的cosine
函数仅适用于一维数组,因此可能具有更高效的实现。 - todaynp.random.rand(1, 400)
而不是np.random.rand(400)
来创建数组以防止重塑),sklearn仍然较慢。我怀疑sklearn设计用于2D数组可能与此有关,但是性能差异还是相当大的。 - Jay Mody