推荐算法: 基于用户的协同过滤算法
- 参考《推荐系统实践》项亮
- 概念: 协同过滤算法
在一个在线个性化推荐系统中,当一个用户 A 需要个性化推荐
时,可以先找到和他有相似兴趣的其他用户,然后把那些用户喜欢的、而用户 A 没有听说过的物品推荐给 A
概念:协同过滤算法
基于用户的协同过滤算法主要包括两个步骤。
(1) 找到和目标用户兴趣相似的用户集合。
(2) 找到这个集合中的用户喜欢的,且目标用户没有听说过的物品推荐给目标用户。
-
如何计算两个用户的兴趣相似度?
协同过滤算法(UserCF), 具体计算如下:
给定用户 u 和用户 v ,令 N(u) 表示用户 u 曾经有过正反馈的物品集合,令 N(v)
为用户 v 曾经有过正反馈的物品集合。那么,我们可以通过如下几种的相似度计算公式简单地计算 u 和 v 的兴趣相似度: -
如何计算: 用户对某商品的感兴趣程度?
得到用户之间的兴趣相似度后, UserCF 算法会给用户推荐和他兴趣最相似的 K 个用户喜欢的物品。
如下的公式度量了 用户 u 对物品 i 的感兴趣程度:
如何使用python编码实现?
假设有用户-商品数据如下:
1::a 1::b 1::c 2::a
2::b 3::c 4::a 4::d
1. 第一步:求出两个用户之间的相似度
使用<用户相似度算法>:如 jaccard相似度算法
得到的结果如下:
2. 第二步:选择最相似的用户群
3. 第三步:过滤&生成商品推荐列表
完整代码如下:
# -*-coding:utf-8-*-
##################第一步:求出两个用户之间的相似度############
#john breese相似度算法
import math
def userLikenessJohnbreese(u,userItemsDict,v,itemUsersDict):
# 相似度
sum = 0.0
setA = set(userItemsDict[u])
setB = set(userItemsDict[v])
common = setA.intersection(setB)
# 循环交集
for i in common:
# 商品的交互用户数==商品i的流行度
iusers = itemUsersDict[i].__len__()
sum = sum + (1.0 / math.log10(iusers + 1))
return sum / math.sqrt(setA.__len__() * setB.__len__())
##################第二步:选择最相似的用户群 ############
def getMostLikeUserGroupK(userItemsDict,itemUsersDict):
# 字典
M = {}
for u,itemsU in userItemsDict.items():
for v,itemsV in userItemsDict.items():
if u < v:
if u not in M.keys():
M[u] = {}
if v not in M.keys():
M[v] = {}
# 计算相似度
ratio = userLikenessJohnbreese(u,userItemsDict,v,itemUsersDict)
M[u][v] = ratio
M[v][u] = ratio
# 对M中每个用的相似度字典按照相似度倒排序
M2 = {}
for k,v in M.items():
M2[k] = sorted(v.items(), key=lambda e: e[1], reverse=True)
return M2
#################第三步:过滤&生成商品推荐列表#############
def recommUserCF(u , K):
# 准备数据:返回的推荐字典[],用户->商品之间的字典, 商品->用户之间的字典
recommDict = {}
userItemsDict = {}
itemUsersDict = {}
file = open("/home/wang/IdeaProjects/big124/mypython/a")
while True :
line = file.readline()
if line != '':
arr = line.replace("\n","").split("\t").split("::")
uid = int(arr[0])
iid = str(arr[1])
# userItemDict
if uid in userItemsDict.keys():
userItemsDict[uid].append(iid)
else :
userItemsDict[uid] = [iid]
# itemUsersDict
if iid in itemUsersDict.keys():
itemUsersDict[iid].append(uid)
else:
itemUsersDict[iid] = [uid]
else:
break ;
# 1, 得到最相似的K个用户
kUsers = getMostLikeUserGroupK(userItemsDict,itemUsersDict)[u][:K]
for v, simV in kUsers:
vitems = userItemsDict[v]
for vi in vitems:
if vi not in userItemsDict[u]:
if vi not in recommDict.keys():
recommDict[vi] = 0.0
recommDict[vi] = recommDict[vi] + simV
#2, 过滤商品,生成推荐列表: { 商品1:sum相似度值 , 商品2:sum相似度值 }
return sorted(recommDict.items() , key = lambda e : e[1] ,reverse=True)
##################测试结果#################
if __name__ =="__main__":
recommList=recommUserCF(2,3)
for i in recommList:
print i
#('c', 1.533734661597076)
#('d', 0.8304820237218405)