包含 NaN 的数组的余弦相似度

数据挖掘 Python 推荐系统 麻木的 余弦距离
2022-03-05 04:44:45

我正在尝试使用 Python 计算余弦相似度,以便根据他们对电影的评分找到相似的用户。正如可以预料的那样,有很多 NaN 值。我正在使用来自 Kaggle 的电影数据集。

当我在两个 nd.arrays 上使用np.dot()时,结果是:'nan'。我已经用np.nansum()检查了除了'nan'之外的一些值。

我不想将所有“nan”值更改为“0”,因为这意味着用户对电影的评分为 0,从而导致用户之间的“错误”相似性。

请给我一些关于如何处理这个问题的建议。

提前致谢。

3个回答

我认为在这样的稀疏数据上考虑余弦相似度几乎没有意义,不仅仅是因为稀疏性(因为它只为密集数据定义),而且因为余弦相似度并不明显是有意义的。例如,将 10 部电影评分为 5 的用户与将这 10 部电影评分为 1 的用户具有完美的相似性。余弦相似度中的大小无关紧要,但在您的领域中却很重要。

它更有可能对用户和项目的一些密集嵌入有意义,例如您从 ALS 获得的内容。

要回答这个问题,您要么需要估算缺失的评分(不要假设为 0,而是平均值或类似值),要么忽略两者中未定义的维度。

你有几种类型的 na 的处理方式。它的代码示例:

def na_handling(df, name_of_strategy):

        #list of stategies -> mean, mode, 0, spefic_value, next_row, previous_row

        if name_of_strategy=="previous_row":
            df.fillna(method="backfill", inplace=True)
            return df
        elif name_of_strategy=="next_row":
            df.fillna(method="ffill", inplace=True)
            return df
        elif name_of_strategy=="0":
            df.fillna(0, inplace=True)
            return df

        elif name_of_strategy=="mean":
            df.fillna(df.mean(), inplace=True)
            return df
        elif name_of_strategy=="mode":
            df.fillna(df.mode(), inplace=True)
            return df
        else:
            print("Wrong specified strategy")


vec1 = na_handling(old_vec, "next_row")
def cosine_sim(df1, df2):

    df1na = df1.isna()
    df1clean = df1[~df1na]
    df2clean = df2[~df1na]

    df2na = df2clean.isna()
    df1clean = df1clean[~df2na]
    df2clean = df2clean[~df2na]


    # Compute cosine similarity
    distance = cosine(df1clean, df2clean)
    sim = 1 - distance

    return sim