【问题标题】:calculate cosine similarity for two columns in a group by in a dataframe在数据框中计算组中两列的余弦相似度
【发布时间】:2018-01-14 02:37:37
【问题描述】:

我有一个数据框df:

AID   VID   FID   APerc   VPerc
1     A     X     0.2     0.5
1     A     Z     0.1     0.3
1     A     Y     0.4     0.9
2     A     X     0.2     0.3
2     A     Z     0.9     0.1
1     B     Z     0.1     0.2
1     B     Y     0.8     0.3
1     B     W     0.5     0.4
1     B     X     0.6     0.3

我想计算所有 AIDVID 对的值 APercVPerc 的余弦相似度。所以上面的结果应该是:

AID   VID   CosSim   
1     A     0.997   
2     A     0.514    
1     B     0.925     

我知道如何分组:df.groupby(['AID','VID'])

我知道如何为整列生成余弦相似度:

from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity(df['APerc'], df['VPerc'])

鉴于我有一个非常大的文件,最好和最快的方法是什么。

【问题讨论】:

    标签: python pandas dataframe cosine-similarity


    【解决方案1】:

    不确定它是否是最快的groupby.apply 通常是这样做的方式:

    (df.groupby(['AID','VID'])
       .apply(lambda g: cosine_similarity(g['APerc'], g['VPerc'])[0][0]))
    
    #AID  VID
    #1    A      0.997097
    #     B      0.924917
    #2    A      0.514496
    #dtype: float64
    

    【讨论】:

    • 使用这些方法但不会返回数据帧。我的意思是把 as_index=False 不允许我使用 AID 和 VID 作为列。我需要它们作为列,并且我需要余弦相似度也是一个具有我可以调用的名称的列。我该怎么做?
    • Chain .rename('CosSim').reset_index() after 应该这样做。
    【解决方案2】:

    Pairwise cosine_similarity 专为二维数组设计,因此您需要在前后进行一些整形。取而代之的是,使用 scipy 的 cosine 距离:

    from scipy.spatial.distance import cosine
    df.groupby(['AID','VID']).apply(lambda x: 1 - cosine(x['APerc'], x['VPerc']))
    Out: 
    AID  VID
    1    A      0.997097
         B      0.924917
    2    A      0.514496
    dtype: float64
    

    对形状为 (10k, 5) 的 df 进行计时,scipy 为 2.87 毫秒,sklearn 为 4.08 毫秒。相当多的 4.08 毫秒可能是由于它输出的警告,因为亚历山大的版本下降到 3.31 毫秒。我怀疑 sklearn 版本在单个二维数组上调用时会变得更快。

    【讨论】:

      【解决方案3】:

      扩展@Psidom的解决方案,在计算cosine_similarity之前将序列转换为numpy数组并重塑:

      (df.groupby(['AID','VID'])
         .apply(lambda g: cosine_similarity(g['APerc'].values.reshape(1, -1), 
                                            g['VPerc'].values.reshape(1, -1))[0][0]))
      

      【讨论】:

        猜你喜欢
        • 2015-05-24
        • 2020-03-16
        • 2021-05-19
        • 2011-05-21
        • 1970-01-01
        • 1970-01-01
        • 2021-05-29
        • 2014-03-25
        相关资源
        最近更新 更多