我有一个非常稀疏的向量df
(超过95%零)的数据集,我正在测量另一个稀疏向量sample
之间的距离。
既然我正在处理非常稀疏的向量,我认为余弦距离的计算速度比欧几里得快得多,但事实并非如此。
这是正常行为吗?或者我做错了什么?或者,在稀疏向量中余弦距离更有效甚至不是真的吗?
(all_distances
包含多种类型的距离,但我们在此讨论的唯一距离是scipy.spatial.distance.euclidean
和scipy.spatial.distance.cosine
)
我的代码
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)))
结果:
余弦的平均时间:0.8034s
欧几里得的平均时间:0.708s
答案 0 :(得分:1)
余弦相似性需要两个输入向量的范数,以及它们之间的点积:
cos(theta) = dot(a,b) / (norm(a) * norm(b))
因此,即使点积仅在a[i]
和b[i]
都非零时累积,您仍然需要累积a
和b
的范数,本身与积累欧几里德距离的工作量差不多。
无论如何,大部分工作都在迭代稀疏向量 - 请注意,它们之间的性能实际上没有太大差异。然而,对差异的合理解释是余弦计算需要稍微多一些算术。