我可以在仅使用非空值的行之间使用余弦相似度吗?

Can I use cosine similarity between rows using only non null values?

我想找出一个查询行和其他 10 个行之间的余弦相似度(或欧氏距离,如果更容易的话)。这些行充满了 nan 值,所以如果列是 nan,它们将被忽略。

例如, 查询:

A   B   C   D   E   F
3   2  NaN  5  NaN  4

df =

A   B   C   D   E   F
2   1   3  NaN  4   5
1  NaN  2   4  NaN  3
.   .   .   .   .   .
.   .   .   .   .   .

所以我只想获得查询的每个非空列与列中 df 中的行之间的余弦相似度。因此,对于 df 中的第 0 行,A、B 和 F 在查询和 df 中都是非空的。

然后我想打印每一行的余弦相似度。

提前致谢

我能想到的最简单的方法就是使用sklearn's cosine_similarity.

from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity(df.fillna(0), df1.fillna(0))
# array([[0.51378309],
#        [0.86958199]])

"ignore" NaN 的最简单方法是在计算相似性时将它们视为零。

对于欧几里德 - https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.nan_euclidean_distances.html 这会在计算中忽略 nan

对于余弦相似度,您不能简单地填写 na,因为这会改变您的相似度得分。相反,获取 df 的子集并计算不包含空值的列之间的余弦相似度。

对于您的示例数据框,这将仅使用 A 列和 F 列计算所有行的余弦相似度,使用 A、B 和 F 计算查询和第 1 行的余弦相似度,使用 A、D 计算查询和第 2 行的余弦相似度, F. 您需要根据要选择的分数进行某种排名来跟进。

combinations = []
df.apply(lambda x: combinations.append(list(x.dropna().index)), axis=1)

# remove duplicate null combinations
combinations = [list(item) for item in set(tuple(row) for row in combinations)]

for i in combinations:
    pdist(df[i].dropna(), metric='cosine')