推荐系统-基于itemCF推荐模型

来源:互联网 发布:无间道3解读知乎 编辑:程序博客网 时间:2024/05/22 01:29

时间:2017年5月
出处:http://blog.csdn.net/csearch/article/details/71244171
声明:版权所有,转载请联系作者并注明出


虽然目前工业界很少再直接通过itemCF来进行推荐,但可以从这个算法中体会到这种集体智慧的应用。

1.ItemCF原理

充分利用集体智慧,即在大量的人群的行为和数据集中收集答案,以帮助我们对整个人群得到统计意义上的结论,推荐的个性化程度高。
基于以下两个出发点:
(1)兴趣相近的用户可能会对同样的东西感兴趣;
(2)用户可能较偏爱与其已购买的东西相类似的商品。
也就是说考虑进了用户的历史习惯,对象客观上不一定相似,但由于人的行为可以认为其主观上是相似的,就可以产生推荐了。

根据所有用户对物品或者信息的评价,发现物品和物品之间的相似度,然后根据用户的历史偏好信息将类似的物品推荐给该用户,如图所示:
这里写图片描述
上图表明基于项目的协同过滤推荐的基本原理,用户A喜欢物品A和物品C,用户B喜欢物品A、物品B和物品C,用户C喜欢物品A,
从这些用户的历史喜好中可以认为物品A与物品C比较类似,喜欢物品A的都喜欢物品C,基于这个判断,用户C也可能喜欢物品C,
所以推荐系统将物品C推荐给用户C。

基于物品的协同过滤关键步骤

(1)计算物品之间的相似度。
(2)根据物品的相似度和用户的历史行为给用户生成推荐列表。
ItemCF算法并不利用物品的内容属性计算物品直接的相似性,她主要通过分析用户的行为记录计算物品直接的相似度。
IUF(Inverse User Frequence)参数,即用户活跃度对数的倒数的参数,认为活跃用户对物品相似度的贡献应该小于不活跃的用户。

2.Python版本代码示例

2.1.读取数据集

from collections import defaultdict# data_path = "../data/ml-1m/ratings.dat";sep = "::"data_path = "../data/ml-100k/u1.base";sep = "\t"fp = open(data_path, "r")user2item_matrix = defaultdict(defaultdict) # 用户到物品的评分矩阵item2user_matrix = defaultdict(defaultdict) # 物品到用户的倒排评分矩阵# UserID \t MovieID \t Score \t Timefor line in open(data_path):    lines = line.strip().split(sep)    userID, movieID, score = lines[0],lines[1],lines[2]    user2item_matrix[userID][movieID] = float(score)    item2user_matrix[movieID][userID] = float(score)fp.close()print("totol users:",len(user2item_matrix))print("totol items:",len(item2user_matrix))

输出:
(‘totol users:’, 943)
(‘totol items:’, 1650)

2.2.计算物-物相似度矩阵

计算物品之间的相似度公式:

wij=|N(i)N(j)||N(i)||N(j)|

* |N(i)|是喜欢物品i的用户数,所以分子是同时喜欢物品i和物品j的用户数。
* 上述公式可以理解为喜欢物品i的用户中有多少比例的用户也喜欢物品j。
* 分母惩罚了物品j的权重,可以避免推荐出热门的物品,从而使推荐系统更致力于挖掘长尾信息。
* 用itemCF算法计算物品的相似首先度时,建立用户-物品倒排表,然后对于每个用户,将他物品列表中的物品两两在共现矩阵C中加1.

import mathdef item_sim_cosine(item2user_matrix):    N = {}    C = defaultdict(defaultdict)  # 物品-物品-共线矩阵    W = defaultdict(defaultdict)  # 物品-物品-相似度矩阵    for i in item2user_matrix.keys():        for j in item2user_matrix.keys():            if i==j:                continue            W[i][j] = len(set(item2user_matrix[i]) & set(item2user_matrix[j])) # 分子:同时喜欢物品i和物品j的用户数            dem = math.sqrt(len(list(item2user_matrix[i])) * len(list(item2user_matrix[j])) * 1.0)             if dem==0.0:                continue            W[i][j] /= dem    return W%time W = item_sim_cosine(item2user_matrix)

输出
CPU times: user 31.2 s, sys: 581 ms, total: 31.7 s
Wall time: 31.5 s

2.3.基于物-物相似度矩阵,进行TopK排序推荐

在得到物品之间的相似度后,itemCF算法通过如下公式计算用户u对一个物品j的兴趣:

puj=iN(u)S(j,K)wijrui

* N(u)是用户喜欢的物品的集合
* S(j,K)是和物品j最相似的K个物品的集合
* w是物品j和i的相似度
* r是用户u对物品i的兴趣。
该公式的含义是,和用户历史上感兴趣的物品越相似的物品,越有可能在用户的推荐列表中获得比较高的排名。

import operatordef recommend(user2item_matrix, user_id, W, K):    '''通过用户userid、训练集数据、用户相似度矩阵进行topN推荐'''    rank=defaultdict(int)    # i为特定用户的电影id,score为其相应评分     for i,score in user2item_matrix[user_id].items():          # 从W物-物相似度矩阵中,获取物品i相似的物品列表,并按照得分进行sorted()的返回值为list        for j,wj in sorted(W[i].items(),key=operator.itemgetter(1),reverse=True)[0:K]:             # 如果j已经在该用户的看过的物品列表中,则忽略掉            if j in user2item_matrix[user_id].keys():                  continue            # 先找出用户评论过的电影集合,对每一部电影id,假设其中一部电影id1,找出与该电影最相似的K部电影,            # 计算出在id1下用户对每部电影的兴趣度,接着迭代整个用户评论过的电影集合,求加权和,再排序,可推荐出前n部电影,我这里取10部。              rank[j]+= score * wj    rank_list = sorted(rank.items(),key=operator.itemgetter(1),reverse=True)[0:10]      return rank_list%time print recommend(user2item_matrix,'3',W,3)

输出
[(‘272’, 6.120247002905049), (‘50’, 4.239718828183374), (‘269’, 4.192092497183264), (‘315’, 4.176401327888063), (‘300’, 3.8573141711075003), (‘286’, 3.6913920128867064), (‘294’, 3.429595429950021), (‘750’, 3.3202801975935095), (‘328’, 3.3156220551840514), (‘348’, 2.856158942397304)]
CPU times: user 15.2 ms, sys: 246 µs, total: 15.5 ms
Wall time: 15.3 ms

1 0