如何找到输入数组和pandas数据框之间的余弦相似度,并返回数据框中最相似的行?

问题描述

我有一个数据集,如下所示,我想找到输入数组和数据帧中到达行之间的余弦相似度,以便识别最相似或重复的行。 下面显示的数据是一个示例,具有多个功能。我想使用min(argmin)查找输入行与数据中的每一行之间的余弦相似度

enter image description here

解决方法

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之间的关系,以查看是否有帮助。