基于用户的协同过滤(余弦相似度)

2020-02-27 15:38:34 浏览数 (2)

@Author:by Runsen

原文:https://blog.csdn.net/weixin_44510615/article/details/89021205

协同过滤

协同过滤简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要。

余弦相似度

余弦相似度用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小。余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。

来个小小案子来理解下

下面是 A、B、C、D 四位顾客对 one 到 seven 总共 7 件商品的评分表

代码语言:javascript复制
import pandas as pd
import numpy as np
data = pd.DataFrame({'one': [4, np.nan, 2, np.nan],
                     'two': [np.nan, 4, np.nan, 5],
                     'three': [5, np.nan, 2, np.nan],
                     'four': [3, 4, np.nan, 3],
                     'five': [5, np.nan, 1, np.nan],
                     'six': [np.nan, 5, np.nan, 5],
                     'seven': [np.nan, np.nan, np.nan, 4]},
                     index = list('ABCD'))
data
OUT:

   one	two	threefourfivesixseven
A	4.0	NaN	5.0	3.0	5.0	NaN	NaN
B	NaN	4.0	NaN	4.0	NaN	5.0	NaN
C	2.0	NaN	2.0	NaN	1.0	NaN	NaN
D	NaN	5.0	NaN	3.0	NaN	5.0	4.0

目标:

  1. 我们要寻找 A 最相似的其他顾客
  2. 预测 A 对 two商品的评分,从而做出是否推荐的判断

用到的是from sklearn.metrics.pairwise import cosine_similarity 这个类

代码语言:javascript复制
from sklearn.metrics.pairwise import cosine_similarity
sim_AB = cosine_similarity(data.loc['A', :].fillna(0).values.reshape(1, -1),
                           data.loc['B', :].fillna(0).values.reshape(1, -1))
sim_AC = cosine_similarity(data.loc['A', :].fillna(0).values.reshape(1, -1),
       					   data.loc['C', :].fillna(0).values.reshape(1, -1))
sim_AB
sim_AC
OUT:
array([[0.18353259]])
array([[0.88527041]])

从上面看出A和C的比较相似,那是因为fillna的原因,在实际生活中真的可以将不知道的值fillna 吗,其实上面的结论是不正确的

下一步就是对数据进行简单的处理

去中心化

让均值为0

代码语言:javascript复制
data_center = data.apply(lambda x: x-x.mean(), axis=1)
data_center

这是再用上面的方法

代码语言:javascript复制
sim_AB = cosine_similarity(data_center.loc['A', :].fillna(0).values.reshape(1, -1),
                          data_center.loc['B', :].fillna(0).values.reshape(1, -1))
sim_AC = cosine_similarity(data_center.loc['A', :].fillna(0).values.reshape(1, -1),
                          data_center.loc['C', :].fillna(0).values.reshape(1, -1))
sim_AB
sim_AC
OUT:
array([[0.30772873]])
array([[-0.24618298]])

去中心化后 A和C的相似度是负的

随便算下 A和D

代码语言:javascript复制
sim_AD = cosine_similarity(data_center.loc['A', :].fillna(0).values.reshape(1, -1),
                           data_center.loc['D', :].fillna(0).values.reshape(1, -1))
sim_AD
OUT:
array([[0.56818182]])

也就是说A和D最像

现在预测 A 对 two商品的评分

用 B和D的评分来计算

(sim_AD*data.loc['D', 'two'] sim_AB*data.loc['B', 'two'])/(sim_AD sim_AB)OUT:array([[4.64867562]])

0 人点赞