推荐算法背后的原理
![](https://img.haomeiwen.com/i3968643/e62781e4d8e6a8aa.png)
![](https://img.haomeiwen.com/i3968643/3c05a895cdda61e4.png)
![](https://img.haomeiwen.com/i3968643/36df9df5f3c1a0b7.png)
![](https://img.haomeiwen.com/i3968643/1fdc816213044f65.png)
![](https://img.haomeiwen.com/i3968643/c9036c91cb46f017.png)
![](https://img.haomeiwen.com/i3968643/1526af2bb5442857.png)
基于物品的协同过滤
基于用户的协同过滤
import pandas as pd
import numpy as np
# 下面是 A、B、C、D 四位顾客对 one 到 seven 总共 7 件商品的评分表
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 # 用户的评分矩阵(效用矩阵)
![](https://img.haomeiwen.com/i3968643/1d4536adb7aa66f4.png)
# 目标:
# 1.我们要寻找 A 最相似的其他顾客(A喜欢某商品,推荐给与A有类似兴趣的其它顾客)
# 2.预测 A 对 two商品的评分,从而做出是否推荐的判断
from sklearn.metrics.pairwise import cosine_similarity
# loc:基于索引取值
# iloc:基于位置取值
# 计算A/B两个评分向量的相似性
sim_AB = cosine_similarity(data.loc['A', :].fillna(0).values.reshape(1, -1),
data.loc['B', :].fillna(0).values.reshape(1, -1))
sim_AB
# array([[0.18353259]])
# 计算A/C两个评分向量的相似性
sim_AC = cosine_similarity(data.loc['A', :].fillna(0).values.reshape(1, -1),
data.loc['C', :].fillna(0).values.reshape(1, -1))
sim_AC
# array([[0.88527041]])
# 结合原始数据,发现当A给某产品打高分的时候,C打了很低的份,即A与C的行为完全相反。而此处的得分却很高,显然不合理。
# 问题出在哪里? 处在我们对NaN值的处理,只有我们非常不喜欢某商品时才会给0分,即0并不是一个中立的得分,直接填充0会引入负面评价。
# 结合数据,对于two/six/seven,A C均为NaN值,都填充为0,因此会带来很好的相似性。
去中心化:
1- 用户对某一产品的得分 - 该用户对所有产品评分的均值。 如果此时再填入0,则0是中性值,不会引入负面评价。
2- 引入公平的评价。 比如A用户,给所有商品都打高分;C用户比较严苛,给所有产品都打低分。 引入去中心化,则会抹平不同用户对商品打分的严苛程度差异。
data_center = data.apply(lambda x: x-x.mean(), axis=1) # 每一行,每个位置减去它在该行的均值
data_center # 去中心化的data
![](https://img.haomeiwen.com/i3968643/c6680d8a4370c771.png)
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_AB
# array([[0.30772873]])
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_AC
# array([[-0.24618298]])
# 此时,得分与评分矩阵的直观映像符合
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
# array([[0.56818182]])
# 计算A用户对Two商品的评分,从而做出是否推荐的判断
# 从上面计算可知,A与B/D相似,与C完全相反/不相似
# 利用相似产品的评分,来计算A对于two的评分
# (AD的相似度*用户D对two商品的评分 + AB的相似度*用户B对于商品two的评分)/(AD的相似度 + AB的相似度)
(sim_AD*data.loc['D', 'two'] + sim_AB*data.loc['B', 'two'])/(sim_AD + sim_AB)
# array([[4.64867562]])
网友评论