基于物品的协同过滤mysql_基于物品协同过滤实现商品推荐系统

本文介绍了如何在某电商平台利用基于物品的协同过滤算法实现商品推荐系统。通过从MySQL数据库获取用户浏览、收藏、购买数据,转换为用户-商品-评分格式,然后计算物品相似度矩阵,实现隐式评分和显式评分的相似度计算,并给出推荐商品的方法。文章还探讨了推荐系统的后续优化问题,如权重更新和推荐新颖性。
摘要由CSDN通过智能技术生成

一、背景

某电商平台,有一批用户浏览、收藏、购买物品的日志数据。实现用户进入APP之后第一页显示商品的个性化推荐。ps:当前阶段,显示数据为随机选取。

二、思考

1、因为是某一品类的特殊电商平台,卖的商品几百种,但是用户几十万。这种情况,考虑使用ItemCF,至于为什么不是UserCF:物品相似度矩阵为 500*500,用户相似度矩阵为 500000*500000。但是也有一个问题,使用物品相似度矩阵会不会使信息丢失更多。

2、类似电影评分数据集,用户-电影-评分数据,要把原始数据转换为用户-物品-评分格式。

浏览:1,收藏:3,购买:5 # 每种行为对应的得分

三、代码实现

1、从mysql数据库读取数据,并转换为 用户-商品-评分 字典

class DataPro:

def __init__(self):

self.train = dict()

logs = mysql.fetchall(select_sql)

for temp in logs: # mysql查询得到的用户日志

user = temp['user_id']

item = temp['product_id']

type = temp['type']

#print(user,item)

score = int(type_score_dict[type])

if user not in self.train.keys():

self.train.setdefault(user, {})

if item not in self.train[user].keys():

self.train[user].setdefault(item,0)

if score > self.train[user][item]:

self.train[user][item] = score

2、可以将结果序列化,保存到本地,在实验过程就不需要查询数据库

# 保存到本地

output = open('../model/data.pkl', 'wb')

pickle.dump(self.train, output)

output.close()

# 读取文件

pkl_file = open('../model/data.pkl', 'rb')

self.data = pickle.load(pkl_file)

3、计算物品-物品相似度矩阵

显示评分和隐式评分的数据,其相似度矩阵的计算公式有所不同

隐式评分:

\[sim(i,j) =\frac{\sum_{u\in N(i) \bigcap N(j)}}{\sqrt{|N(i)||N(j)|}}\tag{1}

\]

\(N(i)\)和\(N(j)\)分别表示喜欢物品\(i\)和物品\(j\)的人数。

显式评分

\[\text{cosine_sim}(i, j) = \frac{\sum\limits_{u \in U_{ij}} r_{ui} \cdot r_{uj}}{\sqrt{\sum\limits_{u \in U_{ij}} r_{ui}^2} \cdot\sqrt{\sum\limits_{u \in U_{ij}} r_{uj}^2}}\tag{2}

\]

其中\(r_{ui}\)和\(r_{uj}\)分别表示用户 \(u\) 对物品 \(i\)和 \(j\) 的评分,\(U_{ij}\)代表同时喜欢物品 \(i\)和 \(j\) 的用户集合。

3.1 基于隐式评分

def ItemSimilarity(self):

# 一个字典,记录 rui*ruj

# 一个字典 记录 rui^2

# 建立物品-物品的共现矩阵

item2item = dict() # 物品-物品的共现矩阵。分子

buy = dict() # 物品被多少个不同用户进行过评分。分母

for user, items in self.data.items():

for i in items.keys():

buy.setdefault(i, 0)

buy[i] += 1

item2item.setdefault(i, {})

for j in items.keys():

if i == j: continue

item2item[i].setdefault(j, 0)

item2item[i][j] += 1

# 计算相似度矩阵

self.similar_matrix = dict()

for i, related_items in item2item.items():

self.similar_matrix.setdefault(i, {})

for j, cij in related_items.items():

self.similar_matrix[i][j] = cij / (math.sqrt(buy[i]) * math.sqrt(buy[j]))

return self.similar_matrix

3.2 基于显式评分

def ItemSimilarity(self):

# 一个字典,记录 rui*ruj

# 一个字典 记录 rui^2

# 建立物品-物品的共现矩阵

item2item = dict() # 物品-物品的共现矩阵。记录rui*ruj,分子

buy = dict() # 物品被多少个不同用户进行过评分。记录rui*rui分母

for user, items in self.data.items():

for i in items.keys():

buy.setdefault(i, 0)

temp = items[i]*items[i]

buy[i] += temp

item2item.setdefault(i, {})

for j in items.keys():

if i == j: continue

item2item[i].setdefault(j, 0)

item2item[i][j] += items[i]*items[j]

# 计算相似度矩阵

self.similar_matrix = dict()

for i, related_items in item2item.items():

self.similar_matrix.setdefault(i, {})

for j, cij in related_items.items():

self.similar_matrix[i][j] = cij / (math.sqrt(buy[i]) * math.sqrt(buy[j]))

return self.similar_matrix

4、相似度矩阵计算完成之后,根据用户id进行商品推荐。需要的参数:K:某个物品其相似物品的个数。N:给用户推荐N个商品。

def get_recommend(self,user_id):

K = 20 # 和某物品相似的k个物品

N = 10 # 推荐最相似的10个物品

rank = {}

watched_items = self.data[user_id]

for item,rating in watched_items.items():

for related_item,w in sorted(self.similar_matrix[item].items(),key=itemgetter(1),reverse=True)[:K]:

rank.setdefault(related_item,0)

rank[related_item] += w*float(rating)

return sorted(rank.items(),key=itemgetter(1),reverse=True)[:N]

四、后续思考

1、用户多次浏览同一个商品,其权重如何在代码中体现

2、基于当前数据的ItemCF完成之后,之后对每天活跃的用户进行推荐结果更新。此时,要实现相似度矩阵的增量更新。

五、电影推荐系统和实际场景中商品推荐系统的区别

对于电影推荐,计算得到推荐的电影即可。

商品推荐,额外的要求是每天推荐结果的新颖性。2020-8-10 和 2020-8-11 两天在首页展示的推荐商品,要求不一样。一个解决方案:过滤掉昨天的推荐物品。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值