【问题标题】:Calculate unrated items with cosine similarity计算具有余弦相似度的未评级项目
【发布时间】:2020-03-18 12:19:52
【问题描述】:

我想用这种方法计算具有余弦相似度的未评级项目。

import numpy as np; import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity

dff = pd.DataFrame(np.random.randint(0, 10, (5, 3)))
temp = dff.copy()
dff
    0   1   2
0   8   0   4
1   6   9   4
2   5   0   5
3   5   9   4
4   9   4   8

cossim = cosine_similarity(dff) # calculate scores.
cossim

array([[1.  , 0.62, 0.95, 0.57, 0.92],
       [0.62, 1.  , 0.61, 1.  , 0.83],
       [0.95, 0.61, 1.  , 0.58, 0.95],
       [0.57, 1.  , 0.58, 1.  , 0.81],
       [0.92, 0.83, 0.95, 0.81, 1.  ]])

我想用余弦相似度得分计算 0 值。

for x in range(0,dff.shape[1]):
    indexes = dff.index[dff.loc[:,x]==0].tolist()
    for y in indexes:
        dff.loc[y,x] = (cossim[y]*temp.loc[:,x].to_numpy()).sum()
dff

    0   1   2
0   8   21.307945   4
1   6   9.000000    4
2   5   34.528532   5
3   5   9.000000    4
4   9   4.000000    8

我用两个for循环计算它? 有没有pythonic的方法来计算它?

有测试数据(真实值)

import numpy as np; import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
data = [['aa',1, 10], ['aa',2,6], ['aa',3, 5],['aa',4],
        ['bb',1], ['bb',2,5], ['bb',3,8],['bb',4,6],
        ['cc',7], ['cc',2], ['cc',3,4],['cc',4,9]] 
df = pd.DataFrame(data, columns = ['full_name','user_id', 'rating'])  
repo_matrix = df.pivot_table(index='full_name', columns='user_id', values='rating')
repo_matrix.replace(np.nan, 0, inplace=True)
repo_matrix
cossim = cosine_similarity(repo_matrix)
display(cossim)
temp = repo_matrix.copy()
repo_matrix = temp.mask(temp==0, cossim@temp)
repo_matrix

所有零都转换为 NaN。 ??

【问题讨论】:

  • 为什么[3,1]cossim[1]*dff.loc[:,1]...代替了?不应该是cossim[3]*dff.loc[:,1]...
  • 1.列值在 cossim(1) 中
  • 所以[4,1] 处的零将获得相同的值?
  • 不,它计算每个单元格的相似度得分。
  • 我用 2 个 for 循环解决它,但我正在寻找一种 Python 的方式

标签: python pandas recommender-systems


【解决方案1】:

您的操作只是矩阵乘法。所以你可以这样做:

 # pass the numpy array instead of dataframe
 # also, you don't need to copy to temp 
 dff = dff.mask(dff==0, cossim @ dff.values)

输出:

   0         1  2
0  8  14.35119  4
1  6   9.00000  4
2  5  14.49324  5
3  5   9.00000  4
4  9   4.00000  8

【讨论】:

  • 它适用于示例数据帧,但适用于真实数据,所有 0 值都转换为 NaN。
  • 你的数据框有列名吗?另外,您是否有一个全为 0/nan 的行/列?
  • 是的,它有一个列名。我将测试数据添加到我的问题中。
  • 这就是问题所在。您可以传递 numpy 数组而不是数据框。查看更新。
  • 我可以问最后一件事吗 :) 我想从每一列中获取 topK 值(其中我们已更改)。我复制数据框以获取这些值(零值)。然后我计划从复制的数据框中获取它们的索引。例如,1 => 14.49 and 14.35
猜你喜欢
  • 2015-05-24
  • 2017-07-07
  • 2018-04-11
  • 2020-03-16
  • 1970-01-01
  • 2017-02-03
  • 2013-06-24
  • 2017-10-19
相关资源
最近更新 更多