前言

在上一篇文章中,介绍了UserCF的实现思路。趁热打铁,这里再介绍一下ItemCF的实现思路。
水平有限,不妥之处还希望大佬多多指正。
数据集与完整代码:https://github.com/ziyuan0014/rec_itemCF

实现思路

数据

本案例所用数据同UserCF的一致,数据样式如下表所示:

user_id content_id score ts
0 1 1 5 874965758
1 1 2 3 876893171
2 1 3 4 878542960
3 1 4 3 876893119
4 1 5 3 889751712

评分矩阵的计算方法同样不变,这里不再进行赘述。

基于物品的协同过滤

根据ItemCF的基本思想,算法要做的事情就是给用户推荐那些和他们之前喜欢的物品相似的物品。在本案例中,整个实现过程同样有三个步骤:

步骤一:计算用户之间的相似度

这里用的依然是余弦相似度:

item_sim_matrix = np.zeros((contentNum,contentNum))
idx = 0
while idx < len(rating):idy = idx + 1while idy < len(rating):item_sim_matrix[idx,idy] = cos_dist(rating[idx],rating[idy])idy = idy +1idx = idx + 1

如果依然用之前所用的评分矩阵计算方法,这一步就无需进行转置,直接依次计算即可。在这一步中值得一提的是:ItemCF算法并不是直接根据物品本身的属性来计算相似度,而是依然通过用户对物品的行为来计算物品之间的相似度。
在这一步中,本案例采用的这种计算方法是默认所有用户对物品的贡献(影响)是相同的,因而有很大的提升空间,这里再安利一篇文章:《ItemCF的演进:狭义 VS 广义》,其中提及了相似度矩阵求的改进,感兴趣的话可以尝试一下,链接:https://zhuanlan.zhihu.com/p/377772010。

步骤二:返回相似物品

选出sim_item_max_len个和物品i最相似的物品,代码如下:

sim_user_dict = {}
sim_user_max_len = 5 # 定义给每个人最大的相似用户数量
for i in range(userNum):temp_series = pd.DataFrame(user_sim_matrix[i],columns=['user_factorize_'+str(i)])sim_user_index = temp_series.sort_values(by = 'user_factorize_'+str(i),ascending = False)[0:sim_user_max_len].index.tolist()for user_index in sim_user_index:if temp_series.iloc[user_index].values == 0:sim_user_index.remove(user_index)sim_user_dict[i] = sim_user_index
real_sim_item_dict = {}real_sim_item_socre_dict = {}sim_item_max_len = 20for i in range(contentNum):temp_series = pd.DataFrame(item_sim_matrix[i],columns=['item_factorize_'+str(i)])sim_item_index = temp_series.sort_values(by = 'item_factorize_'+str(i),ascending = False)[0:sim_item_max_len].index.tolist()sim_item_score = list(temp_series.iloc[sim_item_index].values.reshape(-1))for j in list(range(len(sim_item_score)))[::-1] : # 从后往前遍历if sim_item_score[j] == 0:sim_item_index.pop(j)sim_item_score.pop(j)real_item_index = []for item_factorize_id in sim_item_index:real_item_index.append(reGetContentId(pd_factorize_data,item_factorize_id))real_sim_item_dict[reGetContentId(pd_factorize_data,i)] = real_item_indexreal_sim_item_socre_dict[reGetContentId(pd_factorize_data,i)] = sim_item_score

整体思路依然是先排序取最大的几个index,然后再把其中相似度为0的去掉。需要注意的是,这里在对list进行遍历除0的时候,由于是采用的索引,需要从后往前遍历,保证list.pop()后list与索引之间还能对上号。

步骤三:根据用户的浏览情况进行推荐

代码

user_rec_dict = {}
user_rec_score_dict = {}
userNum = pd_factorize_data['user_factorize_id'].max() + 1
for user_factorize_id in range(userNum):user_data = pd_factorize_data[pd_factorize_data['user_factorize_id'] == user_factorize_id]user_id = reGetUserId(user_data,user_factorize_id)user_list = []user_score_list = []for content in user_data['content_id'].values:item_sim = real_sim_item_dict.get(content)score = user_data[user_data['content_id']==content]['score'].values[0]item_sim_score = real_sim_item_socre_dict.get(content)for i in range(len(item_sim_score)):rec_score = score * item_sim_score[i]if rec_score > 0 and item_sim[i] not in user_list:user_score_list.append(rec_score)user_list.append(item_sim[i])if len(user_list) >0 :user_rec_dict[user_id] = user_listuser_rec_score_dict[user_id] = user_score_list

这里还是定义了两个dict,一个用来存储为每个用户进行推荐的内容id,另一个则用来存储相应内容id的推荐分数。关于不同item的rec_score,这里只取了第一次出现的相似item的score,但是这个分数却并不一定是最高的rec_score,举个例子:用户u喜欢A(5)和B(4)两个物品,这两个物品中的相似物品都有C,而item_sim_score(A,C)=0.2、item_sim_score(A,B)=0.4,而5∗0.2<4∗0.45*0.2<4*0.45∗0.2<4∗0.4。一个比较理想的策略是,先把所有的计算结果都存下来,然后再根据相应的item取分数最高的作为rec_score。
同样的数据集,相比UserCF,这一步943个用户大概跑了两分钟就完成啦。

至此整个算法实现完毕,后续根据项目需求灵活取用即可。

尾言

总的来说,UserCF和ItemCF都属于比较简单的算法,非常适合作为推荐系统的入门,但也确实存在着很多的问题,除了文中提到的相似度计算方法外,还有数据稀疏、头部效应等,因此后续同样出现了很多基于CF改进的推荐算法的研究。
花时间认真复现一遍,打下基础,并在这个过程中对各种细节进行深入了解,还是很值得的。

ItemCF的Python实现相关推荐

  1. 推荐系统 | 基础推荐模型 | GBDT+LR模型 | Python实现

    基础推荐模型--传送门: 推荐系统 | 基础推荐模型 | 协同过滤 | UserCF与ItemCF的Python实现及优化 推荐系统 | 基础推荐模型 | 矩阵分解模型 | 隐语义模型 | PyTor ...

  2. 推荐系统 | 基础推荐模型 | 逻辑回归模型 | LS-PLM | PyTorch实现

    基础推荐模型--传送门: 推荐系统 | 基础推荐模型 | 协同过滤 | UserCF与ItemCF的Python实现及优化 推荐系统 | 基础推荐模型 | 矩阵分解模型 | 隐语义模型 | PyTor ...

  3. python实现ItemCF算法

    毕设要用到推荐算法,于是今天在在网上查找资料,找到这位仁兄的资料https://blog.csdn.net/Gamer_gyt/article/details/51346159 #!/usr/sbin ...

  4. Python推荐系统学习笔记(3)基于协同过滤的个性化推荐算法实战---ItemCF算法(下)

    本文在 Python推荐系统学习笔记(2)基于协同过滤的个性化推荐算法实战---ItemCF算法 一文的基础上,对其基本的ItemCF算法做出改进. 一.相关概念 1.ItemCF中,基于行为(喜好) ...

  5. 推荐算法的Python实现——ItemCF(基于物品的协同过滤)

    1. 数据集 本博客用Movielens-1m数据集的ratings.dat作为推荐数据来训练ItemCF推荐模型.第一列是用户id(user_id).第二列是物品id(item_id).第三列是用户 ...

  6. itemcf的hadoop实现优化(Python)

    原始数据如下: u1 a,d,b,c u2 a,a,c u3 b,d u4 a,d,c u5 a,b,c 计算公式使用:sim = U(i)∩U(j) / (U(i)∪U(j)) 其中: (U(i)∪ ...

  7. 协同过滤推荐算法:UserCF、ItemCF python现实

    目录 一.协同过滤算法 二.基于邻域的算法:UserCF.ItemCF 三.UserCF.ItemCF的改进 一.协同过滤推荐算法 协同过滤算法是指基于用户行为数据设计的推荐算法,主要包括: 1.基于 ...

  8. python数据驱动读取用例_Python Selenium 之数据驱动测试

    数据驱动模式的测试好处相比普通模式的测试就显而易见了吧!使用数据驱动的模式,可以根据业务分解测试数据,只需定义变量,使用外部或者自定义的数据使其参数化,从而避免了使用之前测试脚本中固定的数据.可以将测 ...

  9. python推荐系统-基于Python的推荐系统的设计与实现

    张玉叶 摘  要: 大数据时代的推荐系统可以帮助用户从海量信息中高效地获取自己的潜在需求,是大数据在互联网领域的典型应用.文章介绍了利用Python语言实现的一个基于物品的协同过滤算法推荐系统,给出了 ...

  10. 【知识发现】基于物品的协同过滤推荐算法python实现

    基于物品的协同过滤算法(Item-Based Collaborative Filtering)是目前业界应用最多的算法,亚马逊.Netflix.Hulu.YouTube都采用该算法作为其基础推荐算法. ...

最新文章

  1. java:数组的默认值
  2. python编程能干什么-Python编程一般可以用来做什么
  3. php多个 r n如何过滤,php怎么去掉r n
  4. 大流行后的数据中心非接触式技术
  5. 我的世界服务器高清修复,我的世界1.7.2 skinme高清修复(optifine)兼容版 35+8大型基础包...
  6. [JSOI2010] 满汉全席
  7. SAP Spartacus支持的语言和货币单位的数据源
  8. python股票预测代码_python用线性回归预测股票价格的实现代码
  9. python网页表格读取_是否可以读取网页html表格数据?
  10. SQLite3中的数据类型
  11. 运营商服务器系统,浪潮服务器助力运营商三大支撑系统上云
  12. Ubuntu18.04在线安装JDK1.8
  13. pandas python2_Python随笔 | Pandas入门(二)
  14. Java基础篇之什么是CharArrayReader
  15. Protel DXP2004 中文版 下载及安装
  16. 多语言国家与缩写映射表
  17. 浅谈 Mlp-Mixer(pytorch and keras)
  18. 如何做好抖音?做抖音必学的上热门技巧
  19. DISCUZ!X1模板home空间模板修改说明home.php
  20. 下行L1/L2控制信道

热门文章

  1. c语言文件操作可重入,C语言试题
  2. 稳压管Ir、Izt、Izk、Izm释义
  3. Android studio连接网易MuMu模拟器
  4. 天气预报接口使用及示例
  5. android布局跑马灯,Android自定义跑马灯效果(适合任意布局)
  6. uniapp-登录界面风格-001
  7. Sphinx/coreseek/mysql全文检索
  8. 【推荐系统】推荐算法系列之DSSM双塔模型:Deep Structured Semantic Models for Web Search using Clickthrough Data
  9. Unity3D第三人称Camera视角旋转实现
  10. 基础篇:异步编程不会?我教你啊!CompletableFuture(JDK1.8)