文章目录

  • 案例介绍
  • 数据集加载
  • 相似度计算
  • 备注
  • User-Based CF 预测评分
    • 评分预测公式
    • 实现评分预测predict
    • 实现预测全部评分predict_all
    • 添加过滤规则预测
    • 根据预测评分为指定用户进行TOP-N推荐
  • Item-Based CF 预测评分
    • 评分预测公式

案例介绍

  • 我们要通过两种最基本的实现方案:User-Based CF和Item-Based CF,利用真实的数据来进行案例的分析演练。数据这边我们采用了MovieLens中的数据集,因为实验环境,对于数据量的要求不能特别高,所以我们可以下载ml-latest-small.zip 较小的数据集。进行电影评分的预测,然后为用户实现电影推荐。传送门链接请点击。

数据集加载

  • ratings文件的展示:在做此实验时需要使用使用ratings.csv文件,我们需要保留userid、movieid及ratings列,去掉timestamp列。效果如图所示:
#部分代码,仅供参考
dtype = {"userId": np.int32, "movieId": np.int32, "rating": np.float32}
ratings = pd.read_csv('./ml-latest-small/ratings.csv',dtype=dtype,usecols = range(3))
ratings.head()
  • 构建透视表(user-item的评分矩阵)
#部分代码,仅供参考
ratings_matrix = ratings.pivot_table(index = ['userId'],columns=['movieId'],values='rating')
ratings_matrix

  • 加载ratings.csv,并转换为用户-电影评分矩阵详细代码
import osimport pandas as pd
import numpy as npDATA_PATH = "./ml-latest-small/ratings.csv"
CACHE_DIR = "./cache/"def load_data(data_path):'''加载数据:param data_path: 数据集路径:param cache_path: 数据集缓存路径:return: 用户-物品评分矩阵'''# 数据集缓存地址cache_path = os.path.join(CACHE_DIR, "ratings_matrix.cache")print("开始加载数据集...")if os.path.exists(cache_path):    # 判断是否存在缓存文件print("加载缓存中...")ratings_matrix = pd.read_pickle(cache_path) #python数据序列化文件pickle(数据量较小的情况下可以不使用)print("从缓存加载数据集完毕")else:print("加载新数据中...")# 设置要加载的数据字段的类型dtype = {"userId": np.int32, "movieId": np.int32, "rating": np.float32}# 加载数据,我们只用前三列数据,分别是用户ID,电影ID,已经用户对电影的对应评分ratings = pd.read_csv(data_path, dtype=dtype, usecols=range(3))# 透视表,将电影ID转换为列名称,转换成为一个User-Movie的评分矩阵ratings_matrix = ratings.pivot_table(index=["userId"], columns=["movieId"], values="rating")# 存入缓存文件ratings_matrix.to_pickle(cache_path)print("数据集加载完毕")return  ratings_matrixif __name__ == '__main__':ratings_matrix = load_data(DATA_PATH)print(ratings_matrix)

相似度计算

  • 我们采用皮尔逊相关系数来计算user-movie之间两两相似度。
#部分代码,仅供参考:
user_similar = ratings_matrix.T.corr()
user_similar
item_similar = ratings_matrix.corr()
item_similar


  • 计算user-item两两相似度详细代码实现
def compute_pearson_similarity(ratings_matrix, based="user"):'''计算皮尔逊相关系数:param ratings_matrix: 用户-物品评分矩阵:param based: "user" or "item":return: 相似度矩阵'''user_similarity_cache_path = os.path.join(CACHE_DIR, "user_similarity.cache")item_similarity_cache_path = os.path.join(CACHE_DIR, "item_similarity.cache")# 基于皮尔逊相关系数计算相似度# 用户相似度if based == "user":if os.path.exists(user_similarity_cache_path):print("正从缓存加载用户相似度矩阵")similarity = pd.read_pickle(user_similarity_cache_path)else:print("开始计算用户相似度矩阵")similarity = ratings_matrix.T.corr()similarity.to_pickle(user_similarity_cache_path)elif based == "item":if os.path.exists(item_similarity_cache_path):print("正从缓存加载物品相似度矩阵")similarity = pd.read_pickle(item_similarity_cache_path)else:print("开始计算物品相似度矩阵")similarity = ratings_matrix.corr()similarity.to_pickle(item_similarity_cache_path)else:raise Exception("Unhandled 'based' Value: %s"%based)print("相似度矩阵计算/加载完毕")return similarityif __name__ == '__main__':ratings_matrix = load_data(DATA_PATH)user_similar = compute_pearson_similarity(ratings_matrix, based="user")print(user_similar)item_similar = compute_pearson_similarity(ratings_matrix, based="item")print(item_similar)

备注

  • 以上的实现,仅适用于实验环境。工业、生产环境中,数据量比我们这个demo要大太多很多数据量都是几百GB甚至是TB级别的,而pandas框架是无法支撑起大批量数据的运算的,因此工业生产环境通常会使用Spark、MR等分布式计算框架来实现的。正如前面所说,推荐算法的思想和理念都是统一的,只是业务场景,数据量和环境不同。所以无论使用什么样的平台工具、数据量的大小,其实现原理都是相同的。

User-Based CF 预测评分

评分预测公式

实现评分预测predict

def predict(uid, iid, ratings_matrix, user_similar):'''预测给定用户对给定物品的评分值:param uid: 用户ID:param iid: 物品ID:param ratings_matrix: 用户-物品评分矩阵:param user_similar: 用户两两相似度矩阵:return: 预测的评分值'''print("开始预测用户<%d>对电影<%d>的评分..."%(uid, iid))# 1. 找出uid用户的相似用户similar_users = user_similar[uid].drop([uid]).dropna()# 相似用户筛选规则:正相关的用户similar_users = similar_users.where(similar_users>0).dropna()if similar_users.empty is True:raise Exception("用户<%d>没有相似的用户" % uid)# 2. 从uid用户的近邻相似用户中筛选出对iid物品有评分记录的近邻用户ids = set(ratings_matrix[iid].dropna().index)&set(similar_users.index)finally_similar_users = similar_users.loc[list(ids)]# 3. 结合uid用户与其近邻用户的相似度预测uid用户对iid物品的评分sum_up = 0    # 评分预测公式的分子部分的值sum_down = 0    # 评分预测公式的分母部分的值for sim_uid, similarity in finally_similar_users.iteritems():# 近邻用户的评分数据sim_user_rated_movies = ratings_matrix.loc[sim_uid].dropna()# 近邻用户对iid物品的评分sim_user_rating_for_item = sim_user_rated_movies[iid]# 计算分子的值sum_up += similarity * sim_user_rating_for_item# 计算分母的值sum_down += similarity# 计算预测的评分值并返回predict_rating = sum_up/sum_downprint("预测出用户<%d>对电影<%d>的评分:%0.2f" % (uid, iid, predict_rating))return round(predict_rating, 2)if __name__ == '__main__':ratings_matrix = load_data(DATA_PATH)user_similar = compute_pearson_similarity(ratings_matrix, based="user")# 预测用户1对物品1的评分predict(1, 1, ratings_matrix, user_similar)# 预测用户2对物品28的评分predict(2, 28, ratings_matrix, user_similar)

实现预测全部评分predict_all

def predict_all(uid, ratings_matrix, user_similar):'''预测全部评分:param uid: 用户id:param ratings_matrix: 用户-物品打分矩阵:param user_similar: 用户两两间的相似度:return: 生成器,逐个返回预测评分'''# 准备要预测的物品的id列表item_ids = ratings_matrix.columns# 逐个预测for iid in item_ids:try:rating = predict(uid, iid, ratings_matrix, user_similar)except Exception as e:print(e)else:yield uid, iid, ratingif __name__ == '__main__':ratings_matrix = load_data(DATA_PATH)user_similar = compute_pearson_similarity(ratings_matrix, based="user")for i in predict_all(1, ratings_matrix, user_similar):pass

添加过滤规则预测

  • 例如过滤冷门电影和已经有评分的电影
def _predict_all(uid, item_ids, ratings_matrix, user_similar):'''预测全部评分:param uid: 用户id:param item_ids: 要预测的物品id列表:param ratings_matrix: 用户-物品打分矩阵:param user_similar: 用户两两间的相似度:return: 生成器,逐个返回预测评分'''# 逐个预测for iid in item_ids:try:rating = predict(uid, iid, ratings_matrix, user_similar)except Exception as e:print(e)else:yield uid, iid, ratingdef predict_all(uid, ratings_matrix, user_similar, filter_rule=None):'''预测全部评分,并可根据条件进行前置过滤:param uid: 用户ID:param ratings_matrix: 用户-物品打分矩阵:param user_similar: 用户两两间的相似度:param filter_rule: 过滤规则,只能是四选一,否则将抛异常:"unhot","rated",["unhot","rated"],None:return: 生成器,逐个返回预测评分'''if not filter_rule:item_ids = ratings_matrix.columnselif isinstance(filter_rule, str) and filter_rule == "unhot":'''过滤非热门电影'''# 统计每部电影的评分数count = ratings_matrix.count()# 过滤出评分数高于10的电影,作为热门电影item_ids = count.where(count>10).dropna().indexelif isinstance(filter_rule, str) and filter_rule == "rated":'''过滤用户评分过的电影'''# 获取用户对所有电影的评分记录user_ratings = ratings_matrix.loc[uid]# 评分范围是1-5,小于6的都是评分过的,除此以外的都是没有评分的_ = user_ratings<6item_ids = _.where(_==False).dropna().indexelif isinstance(filter_rule, list) and set(filter_rule) == set(["unhot", "rated"]):'''过滤非热门和用户已经评分过的电影'''count = ratings_matrix.count()ids1 = count.where(count > 10).dropna().indexuser_ratings = ratings_matrix.loc[uid]_ = user_ratings < 6ids2 = _.where(_ == False).dropna().index# 取二者交集item_ids = set(ids1)&set(ids2)else:raise Exception("无效的过滤参数")yield from _predict_all(uid, item_ids, ratings_matrix, user_similar)if __name__ == '__main__':ratings_matrix = load_data(DATA_PATH)user_similar = compute_pearson_similarity(ratings_matrix, based="user")for result in predict_all(1, ratings_matrix, user_similar, filter_rule=["unhot", "rated"]):print(result)

根据预测评分为指定用户进行TOP-N推荐

def top_k_rs_result(k):ratings_matrix = load_data(DATA_PATH)user_similar = compute_pearson_similarity(ratings_matrix, based="user")results = predict_all(1, ratings_matrix, user_similar, filter_rule=["unhot", "rated"])return sorted(results, key=lambda x: x[2], reverse=True)[:k]if __name__ == '__main__':from pprint import pprintresult = top_k_rs_result(20)print(result)

Item-Based CF 预测评分

评分预测公式

  • 这里代码部分就省略了,因为UBCF与IBCF实现代码基本相同。

基于协同过滤的电影评分推荐案例及相关代码相关推荐

  1. 1.3 基于协同过滤的电影推荐案例

    1.3 案例–基于协同过滤的电影推荐 学习目标 应用基于用户的协同过滤实现电影评分预测 应用基于物品的协同过滤实现电影评分预测 1 User-Based CF 预测电影评分 数据集下载 下载地址:Mo ...

  2. 【推荐系统案例】基于协同过滤的电影推荐

    案例--基于协同过滤的电影推荐 1. 数据集下载 2. 数据集加载 3. 相似度计算 4. User-Based CF 预测评分算法实现 5. Item-Based CF 预测评分算法实现 前面我们已 ...

  3. 基于协同过滤的电影推荐

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 1.4 案例--基于协同过滤的电影推荐 学习目标 应用基于用户 ...

  4. python协同过滤电影推荐_基于协同过滤的电影推荐系统的设计与实现

    龙源期刊网 http://www.qikan.com.cn 基于协同过滤的电影推荐系统的设计与实现 作者:张玉叶

  5. 基于协同过滤算法的商品推荐购物电商系统

    一.介绍 商品推荐是针对用户面对海量的商品信息而不知从何下手的一种解决方案,它可以根据用户的喜好,年龄,点击量,购买量以及各种购买行为来为用户推荐合适的商品.在本项目中采用的是基于用户的协同过滤的推荐 ...

  6. 基于协同过滤 算法推荐系统图书推荐猜你喜欢

    基于协同过滤 算法推荐系统图书推荐 一 项目介绍 该项目有前台,有后台,前台主要是首页轮播图,最新发布图书,热门图书,图书总量,图书收藏量,用户注册量,图书分类,图书搜索,图书分页列表,图书详情,图书 ...

  7. 推荐系统(一)基于协同过滤算法开发离线推荐

    什么是离线推荐 所谓的离线推荐其实就是根据用户产生的行为日志,后台设定一个离线统计算法和离线推荐算法的任务来对这些行为日志进行周期性的统计,统计过后的结果数据为前台或者实时分析提供数据的支撑.离线推荐 ...

  8. Python机器学习实战教学——基于协同过滤的电影推荐系统(超详细教学,算法分析)

    注重版权,转载请注明原作者和原文链接 作者:Yuan-Programmer 结尾处有效果展示 文章目录 引言 一.技术原理 (一)推荐算法介绍 (二)主流距离计算法 (三)余弦距离计算法 二.数据介绍 ...

  9. 基于协同过滤算法的书籍推荐 毕业设计-附源码101555

    摘  要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存储达到准 ...

最新文章

  1. zk宕机掉与客户端连接过程记录
  2. Intellij IDEA 新建一个EJB工程(三)
  3. 【springboot基础】配置日志输出级别以及输出位置
  4. unity 打开vs没有解决方案_VS找不到UnityEngine、UnityEngine.UI等引用的解决办法
  5. logback 配置详解
  6. 05使用jmeter里调试一个下单接口
  7. Linux修改时区和时间
  8. android下载 sdk 的两个代理 ,解决下载sdk慢的问题
  9. 转帖科学观点:没有特异性的免疫屏障
  10. gulpfile 编译运行_Gulp基本使用
  11. 免费WEB打印控件(插件)——打天下
  12. 【微信小程序】从零开始搭建一个英语学习小程序01——基础准备
  13. 域控服务器共享盘搭建,搭建域控服务器
  14. Android 开发佳站3
  15. android代码 发警报音,Android 8中的警报重复
  16. 寒霜朋克计算机丢失,Frostpunk寒霜朋克冰汽时代已停止工作修复补丁(Windows6.1-KB2670838-x64)...
  17. APP推广渠道十种精华方法
  18. 定积分的基本性质5 区间可加性
  19. 怎么把手机文件导入华为云服务器,华为手机如何上传数据到云服务器
  20. android系统 视频流录像,Android端海康视频取流,可以实时预览与查看历史录像

热门文章

  1. Mybatis-plus读取(GeoJson)和保存Postgis geography数据
  2. 解决Required XXX parameter ‘XXX‘ is not present问题
  3. 分类决策树考虑了经验风险吗_数据挖掘导论 第4章 分类:基本概念、决策树与模型评估...
  4. 暴力破解之验证码绕过
  5. 鸿蒙微信公众号报名,鸿蒙系统官网2.0报名分享
  6. 业务模块卸载失败定位过程
  7. 【存储知识】NAS存储
  8. PCIe学习(二):PCIe DMA关键模块分析之一
  9. Hue编译安装适配sparksql(hue+livy+sparksql+pyspark)
  10. livy(0.5) on zeppelin(0.8)报No YARN application is found with tag问题解决