推荐系统整理

前言

从今天开始跟着视频学习推荐系统,顺便将CSDN作为备忘录进行记录,也能起到督促自己的作用。也希望这个笔记能够帮助到更多的人。
在介绍利用相似度做推荐前,先创建数据,如创建下列用户的物品喜好表格数据:

users = ['user1','user2','user3','user4','user5']
items = ['item A','item B','item C','item D','item E']

datasets = [[1,0,1,1,0],
            [1,0,0,1,1],
            [1,0,1,0,0],
            [0,1,0,1,1],
            [1,1,1,0,1],]
import pandas as pd
df = pd.DataFrame(datasets, columns=items, index=users)
print(df)

得到:

/item Aitem Bitem Citem Ditem E
user110110
user210011
user310100
user401011
user511101

Jaccard相似度

公式

适合计算bool值 {0,1} 的向量间的相似度(稠密数据)
s i m ( a , b ) = a ∩ b a ∪ b sim(a,b)=\frac{a\cap b}{a\cup b} sim(a,b)=abab

示例

1.计算jaccard相似度

1.1)基于物品(item-based):计算物品A与物品B之间的jaccard相似度

from sklearn.metrics import jaccard_score
#比较对象可以是list, tuple, pd.Series, np.array等等。。
print(jaccard_score(df['item A'], df['item B']))

输出 0.2

1.2)基于用户(user-based):计算用户2与用户3之间的jaccard相似度

from sklearn.metrics import jaccard_score
print(jaccard_score(df.loc['user2'], df.loc['user3']))

输出 0.25

1.3)计算用户两两之间的jaccard相似度

from sklearn.metrics.pairwise import pairwise_distances
df.dtype = bool  #需要制定DataFrame的dtype,否则下一步会报错
# jaccard相似度 = 1 - jaccard距离
user_simi = 1 - pairwise_distances(df, metric="jaccard") # 用户间相似度
# item_simi = 1 - pairwise_distances(df.T, metric="jaccard") # 物品间相似度
user_simi = pd.DataFrame(user_simi, columns=users,index=users)
print('用户向量两两间相似度:', user_simi)

得到:

/user1user2user3user4user5
user11.0000000.500.6666670.20.4
user20.5000001.000.2500000.50.4
user30.6666670.251.0000000.00.5
user40.2000000.500.0000001.00.4
user50.4000000.400.5000000.41.0

2.利用jaccard相似度做推荐
为用户a寻找相似用户B,将这些相似用户B的喜好作为用户a的推荐 (去重)

2.1)取前2个最相似的用户

top2_users = {}
for i in user_simi.index:
    df_ = user_simi.loc[i].drop([i]) # 移除自身
    df_sort = df_.sort_values(ascending=False)
    top2 = list(df_sort.index[:2])
    top2_users[i] = top2
print(top2_users)

得到:
{‘user1’: [‘user3’, ‘user2’],
‘user2’: [‘user4’, ‘user1’],
‘user3’: [‘user1’, ‘user5’],
‘user4’: [‘user2’, ‘user5’],
‘user5’: [‘user3’, ‘user4’]}

2.2)为用户推荐最相似用户喜欢的物品

re_results = {}
for user, sim_users in top2_users.items():
    re_result = []
    for sim_user in sim_users:  # 遍历用户的相似用户
		# 获得相似的用户的喜好
        re_result.extend(df.loc[sim_user].index[df.loc[sim_user] == 1].tolist())
    re_result = set(re_result) # 剔除重复项
    # 剔除用户本身的喜好
    re_result -= set(df.loc[user].index[df.loc[user] == 1].tolist())
    re_results[user] = re_result
print(re_results)

得到:
{‘user1’: {‘item E’},
‘user2’: {‘item C’, ‘item B’},
‘user3’: {‘item E’, ‘item D’, ‘item B’},
‘user4’: {‘item A’, ‘item C’},
‘user5’: {‘item D’}}

Pearson相似度(相关系数)

可看成是减去了平均值的余弦相似度,适合连续数据的比较。取值范围为 [ 1 , − 1 ] [1,-1] [1,1],正数表示正相关,负数表示负相关,0表示无关(稠密数据)

公式

r = ∑ i = 1 n ( x i − x ˉ ) ( y i − y ˉ ) ∑ i = 1 n ( x i − x ˉ ) 2 ∑ i = 1 n ( y i − y ˉ ) 2 r = \frac{\sum_{i=1}^n (x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^n (x_i-\bar{x})^2}\sqrt{\sum_{i=1}^n (y_i-\bar{y})^2}} r=i=1n(xixˉ)2 i=1n(yiyˉ)2 i=1n(xixˉ)(yiyˉ)

示例

pandas中自带了pearson相关系数的计算。以上述pandas表格为例:

1.计算pearson相似度

user_simi = df.T.corr() # 获得节点间pearson相似度(基于用户)
item_simi = df.corr()   # 获得物品间pearson相似度(基于物品)

2.利用pearson相似度做推荐

取与用户i相似度最高的前2个用户j,k,设 r i j r_{ij} rij表示用户i和用户j之间的pearson相似度, s i a s_{ia} sia表示用户i对商品a的评分,则给用户i可能给商品a的评分为:
p r e d ( i , a ) = r i j ∗ s j a + r i k ∗ s k a r i j + r i k pred(i,a) = \frac{r_{ij}*s_{ja}+r_{ik}*s_{ka}}{r_{ij}+r_{ik}} pred(i,a)=rij+rikrijsja+rikska

基于(二分)图的相似度

二分图
通过用户(A,B,C,D)之间的路径数、路径长度和经过的用户数来评价两个用户之间的相关性(稀疏数据)

基于模型的算法

基于矩阵分解

r ⟼ f u s e r × f m o v i e s R n × m ⟼ R n × k × R k × m r \longmapsto f_{user} \times f_{movies} \\ \mathbb{R}^{n\times m} \longmapsto\mathbb{R}^{n\times k}\times \mathbb{R}^{k\times m} rfuser×fmoviesRn×mRn×k×Rk×m
其中 f u s e r f_{user} fuser( R n × k \mathbb{R}^{n\times k} Rn×k)为用户矩阵, f m o v i e s f_{movies} fmovies( R k × m \mathbb{R}^{k\times m} Rk×m)为物品矩阵,k可以看成是影响用户评分的因素。
因此可以理解成:
用户矩阵:k种因素对用户的重要性占比
物品矩阵:物品的k种因素的大小
因此,用户i对某件商品a的评分 s c o r e = f u s e r i , : × f m o v i e s : , a score = f_{user}^{i,:}\times f_{movies}^{:,a} score=fuseri,:×fmovies:,a

ALS(交替最小二乘法)

随机初始化并固定 f u s e r f_{user} fuser,利用公式计算 f m o v i e s f_{movies} fmovies;再固定 f m o v i e s f_{movies} fmovies,计算f_{user};不断迭代直至收敛。

公式

f u s e r = arg ⁡ min ⁡ w ∈ R d ∑ ( r i j − w T f m o v i e s ) 2 + λ ∥ w ∥ 2 2 f_{user}=\mathop{\arg\min}\limits_{w\in \mathbb{R^d}}\sum(r_{ij}-w^Tf_{movies})^2+\lambda \|w\|_2^2 fuser=wRdargmin(rijwTfmovies)2+λw22
同理:
f m o v i e s = arg ⁡ min ⁡ w ∈ R d ∑ ( r i j − w T f u s e r ) 2 + λ ∥ w ∥ 2 2 f_{movies}=\mathop{\arg\min}\limits_{w\in \mathbb{R^d}}\sum(r_{ij}-w^Tf_{user})^2+\lambda \|w\|_2^2 fmovies=wRdargmin(rijwTfuser)2+λw22

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值