问题描述
我有一个数据集,如下所示,我想找到输入数组和数据帧中到达行之间的余弦相似度,以便识别最相似或重复的行。 下面显示的数据是一个示例,具有多个功能。我想使用min(argmin)查找输入行与数据中的每一行之间的余弦相似度
解决方法
有various ways of computing cosine similarity。在这里,我对它们各自如何应用于数据框进行了简要总结。
数据
import pandas as pd
import numpy as np
# Please don't make people do this. You should have enough reps to know that.
np.random.seed(111) # reproducibility
df = pd.DataFrame(
data={
"col1": np.random.randn(5),"col2": np.random.randn(5),"col3": np.random.randn(5),}
)
input_array = np.array([1,2,3])
# print
df
Out[6]:
col1 col2 col3
0 -1.133838 -0.459439 0.238894
1 0.384319 -0.059169 -0.589920
2 1.496554 -0.354174 -1.440585
3 -0.355382 -0.735523 0.773703
4 -0.787534 -1.183940 -1.027967
1。 Sklearn余弦相似度
请注意正确的形状。 2D数据的形状应始终为(#rows,#features)
。还请注意输出形状。
from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity(input_array.reshape((1,-1)),df).reshape(-1)
Out[7]: array([-0.28645981,-0.56882572,-0.44816313,0.11750604,-0.95037169])
2。 Scipy余弦距离
只需将其应用于每一行(axis=1
)。结果与使用sklearn
相同。请注意,这里的余弦相似度为1 - cosine(a1,a2)
。
from scipy.spatial.distance import cosine
df.apply(lambda row: 1 - cosine(row,input_array),axis=1)
Out[10]:
0 -0.286460
1 -0.568826
2 -0.448163
3 0.117506
4 -0.950372
dtype: float64
3。手动计算
与scipy
基本上相同,只是您手动编写公式。
from numpy.linalg import norm
df.apply(lambda row: input_array.dot(row) / norm(input_array) / norm(row),axis=1)
Out[8]:
0 -0.286460
1 -0.568826
2 -0.448163
3 0.117506
4 -0.950372
dtype: float64
还请参考Pearson correlation,cosine similarity and z-score之间的关系,以查看是否有帮助。