我有一个非常稀疏的向量 df
数据集(超过 95% 的零),我正在测量另一个稀疏向量 sample
之间的距离。
现在,由于我正在处理非常稀疏的向量,我假设余弦距离的计算速度会比欧几里德距离快得多,但事实似乎并非如此。
这是正常行为吗?还是我做错了什么?或者余弦距离在稀疏向量中更有效甚至不是真的?
(all_distances
包括许多类型的距离,但我们在这里讨论的只有 scipy.spatial.distance.euclidean
和 scipy.spatial。距离.余弦
)
我的代码
for d_name, d_func in all_distances.items():
tot_time = []
for i in range(100):
start_time = time()
df['distance'] = df.apply(d_func, axis=1, args=(sample,))
df.sort_values(by='distance', ascending=True, inplace=True)
df.drop('distance', axis=1, inplace=True)
df = df.reset_index(drop=True)
tot_time.append(time() - start_time)
print("Mean time for {}: {}s".format(d_name, round(mean(tot_time), 4)))
结果:
Mean time for cosine: 0.8034s
Mean time for euclidean: 0.708s
余弦相似度需要两个输入向量的范数,以及它们之间的点积:
cos(theta) = dot(a,b) / (norm(a) * norm(b))
因此,即使点积仅在 a[i]
和 b[i]
都非零时才累加,您仍然需要累加两者的范数 a
和 b
,它们本身的工作量与累积欧氏距离差不多。
无论如何,大部分工作都将通过稀疏向量进行迭代——请注意,它们之间的性能实际上并没有太大差异。然而,对差异的一个合理解释是余弦计算需要做更多的算术运算。
我是一名优秀的程序员,十分优秀!