推荐系统常见问题(三):TopN 推荐是对训练集中的用户进行推荐,还是对测试集中的用户进行推荐?

从我学习推荐系统以来,一直有个疑问深深的困扰着我,那就是到底是对训练集中的用户进行推荐,还是对测试集中的用户进行推荐呢?之所以一直苦思冥想是因为我认为这关系着我做的实验的的评估效果怎么样,比如 Precision 和 Recall。

一、误区产生的原因 ?

以下是我自己的苦思冥想(深深误区)

以TopN推荐为例,对于按照比例对数据集进行划分成训练集和测试集,那势必会有些用户只在训练集中出现而不在测试集中出现,有些用户只在测试集中出现 ,而不在训练集中出现。

  • 按照对训练集中的用户进行推荐的做法,如果我对一个只在训练集中的用户进行推荐,可实际上他在测试集中压根没有出现过,自然也不会有他消费过的物品,那按照 Precision 的计算方法,对于这个用户来说,他的 Precision 妥妥的为0。

    如果这样的用户很多,那我最后的平均 Precision 不是非常的低?并且这样的做法,有很多只在测试集中出现的用户是不会产生推荐列表的。

  • 那为了加大我实验 Precision的数值,那我只对测试集中的用户进行推荐好了,这样测试集中有哪个用户我就对哪个用户去产生推荐结果,这样想来很完美!

    但我又在疑惑,我要做的是推荐系统啊!我是用训练集里的用户数据进行训练的啊,我为什么不是对训练集中的用户进行推荐???(在机器学习里面这种想法应该是很正常的,我训练的是什么,我预测的就该是什么!)

    而且我在很多论文以及项亮的《推荐系统实践》里面看到的说法都是,对训练集中的用户去进行推荐!

### Top-N 推荐算法的实现与原理 #### 一、Top-N 推荐系统的定义 Top-N 推荐系统旨在向用户推荐一组(通常是 N 个)最有可能感兴趣的项目。这类系统广泛应用于电商、音乐流媒体以及视频平台等领域,通过分析用户的偏好和其他相似用户的行为来进行个性化推荐。 #### 二、基于协同过滤的 Top-N 推荐方法 一种常见的构建 Top-N 推荐的方式是利用协同过滤技术[^2]。该策略主要分为两类: - **基于用户的协同过滤**:计算目标用户与其他所有用户的相似度;对于每一个候选商品,汇总那些对该商品打分较高的邻居们的评分情况,从而预测出当前用户对此产品的潜在兴趣程度。 - **基于项目的协同过滤**:衡量不同产品间的关联强度;当要为某位顾客提供建议时,则优先考虑他过去曾经表现出浓厚兴趣的商品所对应的高相关性的其他物件。 这两种方式的核心在于如何有效地找到“近邻”。通常会采用余弦相似性、皮尔逊相关系数等指标来量化个体之间的亲疏关系。 #### 、优化性能以支持大规模数据上的高效检索 为了确保即使面对海量的历史交互记录也能够迅速响应查询请求,在实际部署过程中往往会对上述基础模型做出改进。例如引入局部敏感哈希(LSH)[^1] 或者借助于像 Faiss 这样的专门库加速最近邻搜索过程。此外还可以结合 Spark 等分布式处理框架完成并行化运算任务,进而提升整体吞吐量水平。 #### 四、具体案例——YouTubeNet 的架构设计思路 考虑到在线服务场景下的特殊需求,某些特定领域内的解决方案可能会更加贴合业务逻辑特点。比如 YouTube 开发团队提出的 YouTubeNet 架构就很好地兼顾到了实时性和准确性两方面的要求[^4]。它采用了多层感知机(MLP)配合矩阵分解(MF),并通过负采样机制缓解冷启动难题的同时提高了训练效率。 ```python import numpy as np from sklearn.metrics.pairwise import cosine_similarity def user_based_recommendation(user_item_matrix, target_user_id, top_n=5): """ 基于用户的协同过滤推荐函数 参数: user_item_matrix (numpy.ndarray): 用户-物品评分矩阵 target_user_id (int): 目标用户的ID编号 top_n (int): 需返回的最大推荐数量 返回值: list: 包含被选中的N件商品索引号组成的列表 """ # 计算用户间相似度矩阵 similarity = cosine_similarity(user_item_matrix) # 获取与指定用户最接近的人群合 similar_users = np.argsort(-similarity[target_user_id])[:top_n] # 统计这些人的共同喜爱但自己尚未接触过的货品清单 recommended_items = [] for other_user in similar_users: liked_by_other_not_me = set(np.where(user_item_matrix[other_user]>0)[0]).difference( set(np.where(user_item_matrix[target_user_id]>0)[0]) ) recommended_items.extend(list(liked_by_other_not_me)) # 对最终结果去重并对频次排序取前几名 item_counts = [(item, recommended_items.count(item)) for item in set(recommended_items)] sorted_items = sorted(item_counts, key=lambda x:x[1], reverse=True)[:top_n] return [i[0] for i in sorted_items] if __name__ == "__main__": # 创建模拟测试用例 ratings_data = [ [5, 3, 0, 1], [4, 0, 0, 1], [1, 1, 0, 5], [1, 0, 0, 4], [0, 1, 5, 4], ] users_ratings = np.array(ratings_data) print("For User ID 0:") result = user_based_recommendation(users_ratings, 0, top_n=2) print(f"The system recommends items {result}") ```
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值