循相似之迹:解锁协同过滤的核心推荐逻辑

在这里插入图片描述



一、引言

在如今这个信息爆炸的时代,互联网上的内容如潮水般涌来。无论是电商平台上琳琅满目的商品,还是视频网站里海量的影视资源,又或是音乐APP中数不尽的歌曲,用户都面临着信息过载的难题。推荐系统就如同一位贴心的助手,能从这茫茫信息中筛选出符合用户兴趣的内容。而协同过滤,作为推荐系统的核心技术之一,发挥着至关重要的作用。

二、协同过滤的基本原理

协同过滤基于一个很直观的假设:如果用户A和用户B对一些物品的评价相似,那么他们对其他物品的喜好可能也相似。这就好比在一个美食爱好者的圈子里,你发现朋友甲和朋友乙都对巧克力蛋糕、冰淇淋等甜食赞不绝口,那很有可能他们对新出的草莓慕斯也会有相同的好感。

从数据层面看,协同过滤依赖于用户 - 物品评分矩阵。假设我们有 m m m个用户和 n n n个物品,这个矩阵就是 m × n m×n m×n的。矩阵里的元素 R i j R_{ij} Rij表示用户 i i i对物品 j j j的评分。要是用户 i i i没给物品 j j j评分, R i j R_{ij} Rij可以设为0或者空值。例如在一个电影评分网站,用户张三给电影《泰坦尼克号》评了4分,那在矩阵里 R 张三 , 泰坦尼克号 R_{张三,泰坦尼克号} R张三,泰坦尼克号就是4;李四还没看过《阿凡达》, R 李四 , 阿凡达 R_{李四,阿凡达} R李四,阿凡达就记为0。通过分析这个矩阵,我们就能挖掘出用户之间以及物品之间隐藏的相似关系。

三、协同过滤的算法类型

(一)基于用户的协同过滤

  1. 计算用户相似度
    确定用户间的相似度是关键一步。常用的相似度度量方法有余弦相似度和皮尔逊相关系数。
    • 余弦相似度:把用户的评分向量想象成空间中的向量。就像在一个多维空间里,用户甲对几部电影的评分构成一个向量,用户乙对同样几部电影的评分构成另一个向量。余弦相似度就是通过计算这两个向量夹角的余弦值来衡量相似程度。公式为:
      s i m ( u , v ) = ∑ i ∈ I R u i × R v i ∑ i ∈ I R u i 2 × ∑ i ∈ I R v i 2 sim(u, v)=\frac{\sum_{i \in I}R_{ui} \times R_{vi}}{\sqrt{\sum_{i \in I}R_{ui}^2} \times \sqrt{\sum_{i \in I}R_{vi}^2}} sim(u,v)=iIRui2 ×iIRvi2 iIRui×Rvi
      这里 u u u v v v是两个用户, I I I是用户 u u u v v v共同评分的物品集合。简单说,就是把两个用户对共同评价过的物品的评分对应相乘,加起来,再除以两个用户各自评分向量的模的乘积。比如用户甲和用户乙都给《盗梦空间》《星际穿越》《蝙蝠侠》评了分,将他们对这三部电影的评分组成向量,代入公式就能算出相似度。值越接近1,说明两人兴趣越相似;越接近0,差异越大。
    • 皮尔逊相关系数:它衡量两个变量的线性相关程度,在协同过滤里判断两个用户评分模式的相似性。公式为:
      s i m ( u , v ) = ∑ i ∈ I ( R u i − R ‾ u ) ( R v i − R ‾ v ) ∑ i ∈ I ( R u i − R ‾ u ) 2 × ∑ i ∈ I ( R v i − R ‾ v ) 2 sim(u, v)=\frac{\sum_{i \in I}(R_{ui}-\overline{R}_{u})(R_{vi}-\overline{R}_{v})}{\sqrt{\sum_{i \in I}(R_{ui}-\overline{R}_{u})^2} \times \sqrt{\sum_{i \in I}(R_{vi}-\overline{R}_{v})^2}} sim(u,v)=iI(RuiRu)2 ×iI(RviRv)2 iI(RuiRu)(RviRv)
      其中, R ‾ u \overline{R}_{u} Ru R ‾ v \overline{R}_{v} Rv分别是用户 u u u v v v的平均评分。这个公式考虑了用户评分的整体趋势,比如有的用户习惯打高分,有的习惯打低分,它能排除这种评分尺度的影响。假设用户丙和用户丁对很多电影的评分整体趋势相似,即便评分数值不同,皮尔逊相关系数也能准确判断他们的相似性。
  2. 筛选邻居用户
    根据算出的相似度,为目标用户挑选与其最相似的 k k k个用户,这 k k k个用户就是目标用户的邻居用户。比如要给用户王五推荐电影,计算王五与其他用户的相似度,选取相似度最高的5个用户作为邻居用户,这5个邻居用户的喜好对给王五推荐电影很关键。
  3. 预测评分与生成推荐列表
    基于邻居用户对目标用户未评分物品的评分,预测目标用户对这些物品的评分。常用加权平均法,预测公式为:
    P u j = ∑ v ∈ N ( u ) sim ( u , v ) × R v j ∑ v ∈ N ( u ) sim ( u , v ) P_{uj}=\frac{\sum_{v \in N(u)}\text{sim}(u, v) \times R_{vj}}{\sum_{v \in N(u)}\text{sim}(u, v)} Puj=vN(u)sim(u,v)vN(u)sim(u,v)×Rvj
    这里 P u j P_{uj} Puj是用户 u u u对物品 j j j的预测评分, N ( u ) N(u) N(u)是用户 u u u的邻居用户集合。比如已找到王五的5个邻居用户,对于王五没看过的一部电影,5个邻居用户有不同评分,且与王五相似度不同。用这个公式,把邻居用户评分乘以相似度加起来,再除以所有邻居用户与王五相似度总和,得到王五对这部电影的预测评分。然后按评分从高到低排序,把评分高的物品推荐给王五。

(二)基于物品的协同过滤

  1. 计算物品相似度
    和基于用户的协同过滤类似,用余弦相似度或皮尔逊相关系数计算物品间相似度,不过是基于物品被用户评分的向量。比如在电商平台,根据用户对不同商品的评分计算商品间相似度。若很多用户对商品A和商品B评分都高,那商品A和商品B相似度可能高。
  2. 查找相似物品
    为目标物品找到与其最相似的 k k k个物品。例如对于一款热门手机,计算它与其他手机的相似度,找出相似度最高的5款手机作为相似物品。
  3. 预测评分与生成推荐列表
    根据目标用户对已评分物品的评分,结合相似物品与已评分物品的相似度,预测目标用户对未评分物品的评分。预测公式与基于用户的协同过滤类似,把用户相似度换成物品相似度。最后按预测评分排序生成推荐列表。

四、协同过滤的应用案例

(一)电商平台的商品推荐

以淘宝为例,当用户浏览并购买了一款运动鞋后,淘宝会依据基于物品的协同过滤算法,找出与这款运动鞋相似的其他运动鞋以及相关运动配件,像运动袜、运动水壶等,并推荐给用户。

下面是基于用户的协同过滤在电商场景下的Python代码示例:

import numpy as np
from sklearn.metrics.pairwise import cosine_similaritydef user_based_collaborative_filtering(user_item_matrix, target_user, k=5):# 计算用户之间的余弦相似度user_similarity = cosine_similarity(user_item_matrix)# 获取目标用户的索引target_user_index = np.where(np.arange(user_item_matrix.shape[0]) == target_user)[0][0]# 获取目标用户与其他用户的相似度得分user_similarity_scores = user_similarity[target_user_index]# 找出与目标用户最相似的k个用户的索引similar_user_indices = np.argsort(user_similarity_scores)[::-1][1:k + 1]# 初始化预测评分向量prediction = np.zeros(user_item_matrix.shape[1])for similar_user in similar_user_indices:# 获取相似用户与目标用户的相似度similarity = user_similarity_scores[similar_user]for item in range(user_item_matrix.shape[1]):# 如果目标用户未对该物品评分,且相似用户对该物品有评分if user_item_matrix[target_user, item] == 0 and user_item_matrix[similar_user, item] != 0:# 累加相似用户评分乘以相似度prediction[item] += similarity * user_item_matrix[similar_user, item]# 对预测评分进行归一化处理prediction = prediction / np.sum(np.abs(user_similarity_scores[similar_user_indices]))# 对预测评分进行排序,获取推荐物品的索引recommended_items = np.argsort(prediction)[::-1]return recommended_items# 示例用户 - 物品评分矩阵,行表示用户,列表示物品
# 这里假设评分范围为0 - 5分,0表示未评分
user_item_matrix = np.array([[5, 3, 0, 1],[4, 0, 0, 1],[1, 1, 0, 5],[1, 0, 0, 4],[0, 1, 5, 4]
])
target_user = 0
recommended_items = user_based_collaborative_filtering(user_item_matrix, target_user)
print("基于用户的协同过滤推荐物品:", recommended_items)

代码中,user_based_collaborative_filtering函数实现基于用户的协同过滤。接收用户 - 物品评分矩阵、目标用户索引和邻居用户数量作为参数。用cosine_similarity函数计算用户间余弦相似度,找到目标用户邻居用户索引。根据邻居用户对未评分物品评分,结合相似度加权求和,预测目标用户对未评分物品评分。最后归一化处理预测评分,返回推荐物品索引。

(二)音乐平台的歌曲推荐

在网易云音乐中,当用户经常收听某歌手的歌曲时,系统会根据基于物品的协同过滤算法,推荐与该歌手风格相似的其他歌手的歌曲给用户。

下面是基于物品的协同过滤在音乐推荐场景下的Python代码示例:

import numpy as np
from sklearn.metrics.pairwise import cosine_similaritydef item_based_collaborative_filtering(user_item_matrix, target_user, k=5):# 计算物品之间的余弦相似度item_similarity = cosine_similarity(user_item_matrix.T)# 获取目标用户的评分向量target_user_ratings = user_item_matrix[target_user]# 获取目标用户已评分物品的索引item_indices = np.where(target_user_ratings != 0)[0]# 初始化预测评分向量prediction = np.zeros(user_item_matrix.shape[1])for item in item_indices:# 找出与当前物品最相似的k个物品的索引similar_item_indices = np.argsort(item_similarity[item])[::-1][1:k + 1]for similar_item in similar_item_indices:# 获取相似物品与当前物品的相似度similarity = item_similarity[item, similar_item]for other_item in range(user_item_matrix.shape[1]):# 如果目标用户未对该物品评分,且相似物品对应的用户评分不为0if target_user_ratings[other_item] == 0 and user_item_matrix[:, similar_item][other_item] != 0:# 累加相似物品评分乘以相似度prediction[other_item] += similarity * user_item_matrix[:, similar_item][other_item]# 对预测评分进行归一化处理prediction = prediction / np.sum(np.abs(item_similarity[item_indices, :][:, similar_item_indices]), axis=1)# 对预测评分进行排序,获取推荐物品的索引recommended_items = np.argsort(prediction)[::-1]return recommended_items# 示例用户 - 物品评分矩阵,行表示用户,列表示歌曲
# 这里假设评分范围为0 - 5分,0表示未评分
user_item_matrix = np.array([[5, 3, 0, 1],[4, 0, 0, 1],[1, 1, 0, 5],[1, 0, 0, 4],[0, 1, 5, 4]
])
target_user = 0
recommended_items = item_based_collaborative_filtering(user_item_matrix, target_user)
print("基于物品的协同过滤推荐物品:", recommended_items)

代码中,item_based_collaborative_filtering函数实现基于物品的协同过滤。接收用户 - 物品评分矩阵、目标用户索引和相似物品数量作为参数。计算物品间余弦相似度得到物品相似度矩阵。找到目标用户已评分歌曲索引,根据相似物品与已评分物品相似度,结合目标用户对已评分物品评分,预测目标用户对未评分歌曲评分。最后归一化处理预测评分,返回推荐歌曲索引。

五、协同过滤面临的挑战与解决方案

(一)数据稀疏性问题

实际中,用户 - 物品评分矩阵往往很稀疏,因为用户通常只对少量物品评分。数据稀疏会导致算出的相似度不准确,影响推荐效果。

解决办法可以用降维技术,像奇异值分解(SVD),把高维评分矩阵分解成低维矩阵,减少稀疏性;也能引入辅助信息,比如物品类别、用户属性等,丰富数据。

(二)冷启动问题

冷启动包括新用户冷启动和新物品冷启动。新用户加入系统没历史评分数据,无法算与其他用户相似度;新物品加入系统没人对其评分,无法算与其他物品相似度。

对于新用户冷启动,可用基于内容的推荐方法,根据用户注册信息(年龄、性别、兴趣爱好等)推荐相关物品;对于新物品冷启动,可先人工标注或基于内容分析,与已有物品建立联系,再推荐。

六、总结

协同过滤是推荐系统的经典技术,原理简单、易实现,在电商、音乐、视频等很多领域广泛应用。不过它也面临数据稀疏性和冷启动等问题。随着技术发展,可结合深度学习、内容推荐等其他技术改进协同过滤算法,提升推荐系统性能和准确性,给用户更个性化、精准的推荐服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/43280.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RuoYi基础学习

1 若依搭建 前后端分离版本:RuoYi-Vue利用SpringBoot作为后端开发框架,与Vue.js结合,实现了前后端分离的开发模式。这种架构有助于提高开发效率,前后端可以独立开发和部署,更适合现代化的Web应用开发。 RuoYi-Vue3&a…

Docker 安装部署Harbor 私有仓库

Docker 安装部署Harbor 私有仓库 系统环境:redhat x86_64 一、首先部署docker 环境 定制软件源 wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repoyum install -y yum-utils device-mapper-persistent-data lvm2…

【Basys3】外设-灯和数码管

灯 约束文件 set_property PACKAGE_PIN W5 [get_ports CLK] set_property PACKAGE_PIN U18 [get_ports rst] set_property PACKAGE_PIN U16 [get_ports {led[0]}] set_property PACKAGE_PIN E19 [get_ports {led[1]}] set_property PACKAGE_PIN U19 [get_ports {led[2]}] set…

【Django】教程-1-安装+创建项目+目录结构介绍

欢迎关注我!后续会更新django教程。一周2-3更,欢迎跟进,本周会更新第一个Demo的单独一个模块的增删改查【Django】教程-4-一个增删改查的Demo【Django】教程-2-前端-目录结构介绍【Django】教程-3-数据库相关介绍 1.项目创建 1.1 安装 Djan…

蓝桥杯 之 二分

文章目录 习题肖恩的n次根分巧克力2.卡牌 二分是十分重要的一个算法,常常用于求解一定范围内,找到满足条件的边界值的情况主要分为浮点数二分和整数二分二分问题,最主要是写出这个check函数,这个check函数最主要就是使用模拟的方法…

SpringBoot集成腾讯云OCR实现身份证识别

OCR身份证识别 官网地址&#xff1a;https://cloud.tencent.com/document/product/866/33524 身份信息认证&#xff08;二要素核验&#xff09; 官网地址&#xff1a;https://cloud.tencent.com/document/product/1007/33188 代码实现 引入依赖 <dependency><…

2025年3月电子学会c++五级真题

结绳 #include <bits/stdc.h> using namespace std;int n,a[10010];int main() {cin>>n;for(int i 0;i<n;i){cin>>a[i];}sort(a0,an);//将a数组从小到大排序double sum 0;for(int i 0;i<n;i){sum (suma[i])/2;}cout<<(int)sum;return 0; } 最…

Typora使用Gitee作为图床

Typora使用Gitee作为图床 文章目录 Typora使用Gitee作为图床Gitee准备图床仓库下载安装软件安装插件 配置Typora Gitee准备图床仓库 新建一个仓库右上角下拉->设置->安全设置->私人令牌->生成新令牌&#xff0c;注意将令牌保存&#xff08;只会出现一次&#xff0…

QT音乐播放器(1):数据库保存歌曲

实现功能&#xff1a;用数据库保存本地导入和在线搜索的歌曲记录 目录 一. 保存本地添加的歌曲 1. 使用QSettings &#xff08;1&#xff09;在构造函数中&#xff0c;创建对象。 &#xff08;2&#xff09;在导入音乐槽函数中&#xff0c;保存新添加的文件路径&#xff0c…

SQLAlchemy关键词搜索技术深度解析:从基础过滤到全文检索

在数据驱动的应用开发中&#xff0c;基于关键词的模糊查询是常见的业务需求。SQLAlchemy作为Python生态中最流行的ORM框架&#xff0c;提供了多种实现关键词搜索的技术方案。本文将从性能、适用场景和技术复杂度三个维度&#xff0c;系统对比分析SQLAlchemy中关键词搜索的最佳实…

css属性列举

介绍 CSS word-spacing 属性&#xff0c;用于指定段字之间的空间&#xff0c;例如&#xff1a; p {word-spacing:30px; }word-spacing属性增加或减少字与字之间的空白。 注意&#xff1a; 负值是允许的。 浏览器支持 表格中的数字表示支持该属性的第一个浏览器版本号。 属…

python实现股票数据可视化

最近在做一个涉及到股票数据清洗及预测的项目&#xff0c;项目中需要用到可视化股票数据这一功能&#xff0c;这里我与大家分享一下股票数据可视化的一些基本方法。 股票数据获取 在经过多次尝试后&#xff0c;发现了一个

从 JDK 11 到 JDK 17:OpenRewrite 实战 Spring Boot 升级指南

一、为什么选择 OpenRewrite 升级&#xff1f; 在 Spring Boot 项目升级 JDK 的过程中&#xff0c;我们面临两个核心痛点&#xff1a; 语法兼容性问题&#xff08;如废弃的 API、新的关键字&#xff09;依赖版本冲突&#xff08;特别是 Spring Boot 与 JDK 版本的匹配&#x…

交换技术综合实验

一、实验拓扑 二、实验要求 内网IP地址使用172.16.0.0/16分配。 SW1和SW2之间互为备份。 VRRP/STP/VLAN/Eth-trunk均使用。 所有PC通过DHCP获取IP地址。 ISP只能配置IP地址。 所有电脑可以正常访问ISP路由器。 三、实验步骤 基于172.16.0.0/16进行划分 172.16.2.0/24&…

【Linux】了解基础指令(超详细)

目录 【whoami】指令【pwd】指令【mkdir】指令【touch】指令【ls】指令文件的扩展内容 【cd】指令相对路径和绝对路径(.和..存在的原因)绝对路径相对路径 【rm】指令【man】命令【less】指令echo指令重定向操作追加重定向 cat 指令输入重定向 管道操作(组合指令)查找三剑客find…

基于改进粒子群算法的多目标分布式电源选址定容规划(附带Matlab代码)

通过分析分布式电源对配电网的影响&#xff0c;以有功功率损耗、电压质量及分布式电源总容量为优化目标&#xff0c;基于模糊理论建立了分布式电源在配电网中选址定容的多目标优化模型&#xff0c;并提出了一种改进粒子群算法进行求解。在算例仿真中&#xff0c;基于IEEE-14标准…

26_ajax

目录 了解 接口 前后端交互 一、安装服务器环境 nodejs ajax发起请求 渲染响应结果 get方式传递参数 post方式传递参数 封装ajax_上 封装ajax下 了解 清楚前后端交互就可以写一些后端代码了。小项目 现在写项目开发的时候都是前后端分离 之前都没有前端这个东西&a…

OJ题:移动零

双指针法 c 语言实现 void moveZeroes(int* nums, int numsSize) {int dest,cur; //创建临时指针和目标指针destcur0;//出初始化while(cur<numsSize)//遍历{if(nums[cur]!0){swap(&nums[cur],&nums[dest]);cur;dest;}else{cur;}}} 思路是建立两个指针&#xff0…

Kubernetes对象基础操作

基础操作 文章目录 基础操作一、创建Kubernetes对象1.使用指令式命令创建Deployment2.使用指令式对象配置创建Deployment3.使用声明式对象配置创建Deployment 二、操作对象的标签1.为对象添加标签2.修改对象的标签3.删除对象标签4.操作具有指定标签的对象 三、操作名称空间四、…