【推荐系统】{1} —— 基于用户的协同过滤算法

2023-11-14

协同过滤(英语:Collaborative Filtering,简称CF),简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人透过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要。——维基百科


基于用户的协同过滤算法(简称UserCF)

在一个在线个性化推荐系统中,当一个用户A需要个性化推荐时,可以先找到和他有相似兴趣的其他用户,然后把那些用户喜欢的、而用户A没有听说过的物品推荐给A。这种方法称为基于用户的协同过滤算法。

举个例子:

用户/物品 物品A 物品B 物品C 物品D
用户A 推荐给用户A
用户B
用户C
要实现基于用户的协同过滤,需要的步骤:
  1. 收集用户偏好
  2. 通过计算相似度找到与目标用户相似的用户
  3. 将相似用户喜欢的、且目标用户没有听说过的物品推荐给目标用户

一、计算两个用户的兴趣相似度

其中关键的一步就是计算两个用户的兴趣相似度。

协同过滤算法主要利用行为的相似度计算兴趣的相似度。给定用户 u u u 和用户 v v v ,令 N ( u ) N(u) N(u) 表示用户 u u u 曾经有过正反馈的物品集合,令 N ( v ) N(v) N(v) 为用户 v v v 曾经有过正反馈的物品集合。则可以通过计算余弦相似度简单地计算 u u u v v v 的兴趣相似度: w u v = ∣ N ( u ) ∩ N ( v ) ∣ ∣ N ( u ) ∪ N ( v ) ∣ w_{uv} = \frac{|N(u)\cap{N(v)|}}{\sqrt{|N(u)\cup{N(v)|}}} wuv=N(u)N(v) N(u)N(v)


例子:

图片来源

如图, A A A B B B C C C D D D 为用户, a a a b b b c c c d d d e e e 为物品。

利用余弦相似度公式计算他们之间的兴趣相似度分别为: w A B = ∣ { a , b , d } ∩ { a , c } ∣ ∣ { a , b , d } ∣    ∣ { a , c } ∣ = 1 6 w_{AB} = \frac{|{\{ a,b,d\}}\cap\{{a,c}\}|}{\sqrt{|\{a,b,d\}|\,\,|\{a,c\}}|}=\frac{1}{\sqrt{6}} wAB={a,b,d}{a,c} {a,b,d}{a,c}=6 1

w A C = ∣ { a , b , d } ∩ { b , e } ∣ ∣ { a , b , d } ∣    ∣ { b , e } ∣ = 1 6 w_{AC} = \frac{|{\{ a,b,d\}}\cap\{{b,e}\}|}{\sqrt{|\{a,b,d\}|\,\,|\{b,e\}}|}=\frac{1}{\sqrt{6}} wAC={a,b,d}{b,e} {a,b,d}{b,e}=6 1

w A C = ∣ { a , b , d } ∩ { c , d , e } ∣ ∣ { a , b , d } ∣    ∣ { c , d , e } ∣ = 1 3 w_{AC} = \frac{|{\{ a,b,d\}}\cap\{{c,d,e}\}|}{\sqrt{|\{a,b,d\}|\,\,|\{c,d,e\}}|}=\frac{1}{3} wAC={a,b,d}{c,d,e} {a,b,d}{c,d,e}=31
但事实上,很多用户相互之间并没有对同样的物品产生过行为,即 ∣ N ( u ) ∩ N ( v ) ∣ = 0 |N(u)\cap{N(v)}|=0 N(u)N(v)=0


因此换一种思路,我们可以首先计算出 ∣ N ( u ) ∩ N ( v ) ∣ ≠ 0 |N(u)\cap{N(v)}|≠0 N(u)N(v)=0 的用户对 ( u , v ) (u,v) (u,v) ,然后再对这种情况除以分母 ∣ N ( u ) ∪ N ( v ) ∣ \sqrt{{|N(u)\cup{N(v)|}}} N(u)N(v)

为此,可以首先建立 物 品 − > 用 户 物品->用户 > 的倒排表。令稀疏矩阵 C [ u ] [ v ] = ∣ N ( u ) ∩ N ( v ) ∣ C[u][v]=|N(u)\cap{N(v)}| C[u][v]=N(u)N(v) 。因此,可以遍历倒排表中每个物品对应的用户列表,将用户列表中的两两用户对应的 C [ u ] [ v ] C[u][v] C[u][v] 同时加 1 1 1,最终就可以得到所有用户之间不为 0 0 0 C [ u ] [ v ] C[u][v] C[u][v]

代码实现如下:

def UserSimilarity(train):
	# 建立倒排表
	item_users = dict()
	for u, items in train.items():
		for i in items.keys():
			if i not in item_users:
				item_users[i] = set()
			item_users[i].add(u)
	
	# 修改相似度矩阵
	C = dict()
	N = dict()
		for i, users in item_users.items():
			for u in users:
				N[u] += 1
				for V in users:
					if u == v:
						continue
					C[u][v] += 1
	
	# 计算相似度矩阵
	W = dict()
	for u, related_users in C.items():
		for V, cuv in related_users.items():
			W[u][v] = cuv / math.sqrt(N[u] * N[v])
	return W

以上图的用户行为解释上述算法。首先,需要建立 物 品 − > 用 户 物品->用户 > 的倒排表(如图1)。然后建立一个 4 × 4 4×4 4×4 的用户相似度矩阵 W W W,对于物品 a a a,将 W [ A ] [ B ] W[A][B] W[A][B] W [ B ] [ A ] W[B][A] W[B][A] 1 1 1,对于物品 b b b,将 W [ A ] [ C ] W[A][C] W[A][C] W [ C ] [ A ] W[C][A] W[C][A] 1 1 1,以此类推(如图2)。扫描完所有物品后,我们可以得到最终的 W W W 矩阵。 此处 W W W 是余弦相似度中的分子部分,将 W W W 除以分母即可得到最终的用户兴趣相似度(如图3)。

图片来源


二、进行推荐

得到用户之间的兴趣相似度后, U s e r C F UserCF UserCF 算法会给用户推荐和他兴趣最相似的 K K K 个用户喜欢的物品。以下公式度量了 U s e r C F UserCF UserCF 算法中用户 u u u 对物品 i i i 的感兴趣程度: p ( u , i ) = ∑ v ∈ S ( u , K ) ∩ N ( i ) w u v r v i p(u,i)=\displaystyle \sum_{v\in{S(u,K)\cap{N(i)}}}w_{uv}r_{vi} p(u,i)=vS(u,K)N(i)wuvrvi

K是 U s e r C F UserCF UserCF 算法的一个重要参数

其中, S ( u , K ) S(u,K) S(u,K) 包含和用户 u u u 兴趣最接近的 K K K 个用户, N ( i ) N(i) N(i) 是对物品 i i i 有过行为的用户集合, w u r w_{ur} wur
是用户 u u u 和用户 v v v 的兴趣相似度, r v i r_{vi} rvi 代表用户 v v v 对物品 i i i 的兴趣,因为使用的是单一行为的隐反馈数据(否则使用评分等指标),所以所有的 r v i = 1 r_{vi}=1 rvi=1

评分可以经过归一化处理

代码如下:

def Recommend(user, train, W):
	rank = dict()
	interacted_items = train[user]
	for v, wuv in sorted (W[u].items, key=itemgetter(1), reverse=True)[0:K]:
		for i, rvi in train[v].items:
			if i in interacted_items:
				# 过滤互动过的项目
				continue
			rank[i] += wuv * rvi
	return rank

利用上述 U s e r C F UserCF UserCF 算法,可以给上述图1、2、3的用户 A A A 进行推荐。选取 K = 3 K=3 K=3,用户 A A A 对物品 c c c e e e 没有过行为,因此可以把这两个物品推荐给用户 A A A。相似用户则是 B B B C C C D D D,他们喜欢过并且 A A A 没有喜欢过的物品有 c c c e e e。根据 U s e r C F UserCF UserCF 算法,用户 A A A 对物品 c c c e e e 的兴趣是: p ( A , c ) = w A B × 1 + w A D × 1 = 1 6 + 1 9 = 0.7416 p(A,c)=w_{AB} ×1+ w_{AD} ×1= \frac{1}{\sqrt{6}}+\frac{1}{\sqrt{9}}=0.7416 p(A,c)=wAB×1+wAD×1=6 1+9 1=0.7416 p ( A , e ) = w A C × 1 + w A D × 1 = 1 6 + 1 9 = 0.7416 p(A,e)=w_{AC}×1+ w_{AD} ×1= \frac{1}{\sqrt{6}}+\frac{1}{\sqrt{9}}=0.7416 p(A,e)=wAC×1+wAD×1=6 1+9 1=0.7416


用户相似度计算的改进:

两个用户对冷门物品采取过同样的行为比热门物品更能说明他们兴趣的相似度。因此,为了防止热门物品的影响,提出如下公式计算用户的兴趣相似度: w u v = ∑ i ∈ N ( u ) ∩ N ( v ) 1 l o g 1 + ∣ N ( i ) ∣ ∣ N ( u ) ∣ ∣ N ( v ) ∣ w_{uv}=\frac{\displaystyle \sum_{i\in{N(u)\cap{N(v)}}}\frac{1}{log1+|N(i)|}}{\sqrt{|N(u)||N(v)|}} wuv=N(u)N(v) iN(u)N(v)log1+N(i)1

上述公式通过 1 l o g 1 + ∣ N ( i ) ∣ \frac{1}{log1+|N(i)|} log1+N(i)1 惩罚了用户 u u u 和用户 v v v 共同兴趣列表中热门物品对他们相似度的影响。

基于上述用户相似度公式的算法记为 U s e r − I I F User-IIF UserIIF 算法。

代码如下:

def UserSimilarity(train):
	# 建立倒排表
	item_users = dict()
	for u, items in train.items():
		for i in items.keys():
			if i not in item_users:
				item_users[i] = set()
			item_users[i].add(u)
	# 统计相似度矩阵
	C = dict()
	N = dict()
	for i, users in item_users.items():
		for u in users:
			N[u] += 1
			for v in users: 
				if u == v:
					continue
				C[u][v] += 1 / math.1og(1 + len(users))
	# 计算相似度矩阵
	W = dict()
	for u, related_users in C.items():
		for v, cuv in related.users.items():
			W[u][v] = cuv / math.sqrt(N[u] * N[v])
	return W

U s e r C F UserCF UserCF 算法存在的问题:
  • 对于一个新用户,很难找到相似用户。
  • 对于一个物品,所有相似用户都在其上没有多少行为。
  • 矩阵稀疏。
  • 用户量越来越大
  • 人类善变

参考资料:《推荐系统实践》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【推荐系统】{1} —— 基于用户的协同过滤算法 的相关文章

  • 无法“安装”plpython3u - postgresql

    我正在尝试在 postgresql 中使用 python 语言 像这样的事情 create or replace function test a integer returns integer as if a 2 0 return even
  • 使用 pythonbrew 编译 Python 3.2 和 2.7 时出现问题

    我正在尝试使用构建多个版本的 python蟒蛇酿造 http pypi python org pypi pythonbrew 0 7 3 但我遇到了一些测试失败 这是在运行的虚拟机上 Ubuntu 8 04 32 位 当我使用时会发生这种情
  • 在 python 程序中合并第三方库的最佳实践是什么?

    下午好 我正在为我的工作编写一个中小型Python程序 该任务需要我使用 Excel 库xlwt and xlrd 以及一个用于查询 Oracle 数据库的库 称为CX Oracle 我正在通过版本控制系统 即CVS 开发该项目 我想知道围
  • Python 的键盘中断不会中止 Rust 函数 (PyO3)

    我有一个使用 PyO3 用 Rust 编写的 Python 库 它涉及一些昂贵的计算 单个函数调用最多需要 10 分钟 从 Python 调用时如何中止执行 Ctrl C 好像只有执行结束后才会处理 所以本质上没什么用 最小可重现示例 Ca
  • Django 管理员在模型编辑时间歇性返回 404

    我们使用 Django Admin 来维护导出到我们的一些站点的一些数据 有时 当单击标准更改列表视图来获取模型编辑表单而不是路由到正确的页面时 我们会得到 Django 404 页面 模板 它是偶尔发生的 我们可以通过重新加载三次来重现它
  • 如何在flask中使用g.user全局

    据我了解 Flask 中的 g 变量 它应该为我提供一个全局位置来存储数据 例如登录后保存当前用户 它是否正确 我希望我的导航在登录后在整个网站上显示我的用户名 我的观点包含 from Flask import g among other
  • 使用 matplotlib 绘制时间序列数据并仅在年初显示年份

    rcParams date autoformatter month b n Y 我正在使用 matpltolib 来绘制时间序列 如果我按上述方式设置 rcParams 则生成的图会在每个刻度处标记月份名称和年份 我怎样才能将其设置为仅在每
  • Python - StatsModels、OLS 置信区间

    在 Statsmodels 中 我可以使用以下方法拟合我的模型 import statsmodels api as sm X np array 22000 13400 47600 7400 12000 32000 28000 31000 6
  • Flask 会话变量

    我正在用 Flask 编写一个小型网络应用程序 当两个用户 在同一网络下 尝试使用应用程序时 我遇到会话变量问题 这是代码 import os from flask import Flask request render template
  • AWS EMR Spark Python 日志记录

    我正在 AWS EMR 上运行一个非常简单的 Spark 作业 但似乎无法从我的脚本中获取任何日志输出 我尝试过打印到 stderr from pyspark import SparkContext import sys if name m
  • 绘制方程

    我正在尝试创建一个函数 它将绘制我告诉它的任何公式 import numpy as np import matplotlib pyplot as plt def graph formula x range x np array x rang
  • 添加不同形状的 numpy 数组

    我想添加两个不同形状的 numpy 数组 但不进行广播 而是将 缺失 值视为零 可能最简单的例子是 1 2 3 2 gt 3 2 3 or 1 2 3 2 1 gt 3 2 3 1 0 0 我事先不知道形状 我正在弄乱每个 np shape
  • Flask如何获取请求的HTTP_ORIGIN

    我想用我自己设置的 Access Control Allow Origin 标头做出响应 而弄清楚请求中的 HTTP ORIGIN 参数在哪里似乎很混乱 我在用着烧瓶 0 10 1 以及HTTP ORIGIN似乎是这个的特点之一object
  • 在Python中获取文件描述符的位置

    比如说 我有一个原始数字文件描述符 我需要根据它获取文件中的当前位置 import os psutil some code that works with file lp lib open path to file p psutil Pro
  • IO 密集型任务中的 Python 多线程

    建议仅在 IO 密集型任务中使用 Python 多线程 因为 Python 有一个全局解释器锁 GIL 只允许一个线程持有 Python 解释器的控制权 然而 多线程对于 IO 密集型操作有意义吗 https stackoverflow c
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 无法在 Python 3 中导入 cProfile

    我试图将 cProfile 模块导入 Python 3 3 0 但出现以下错误 Traceback most recent call last File
  • Pandas:merge_asof() 对多行求和/不重复

    我正在处理两个数据集 每个数据集具有不同的关联日期 我想合并它们 但因为日期不完全匹配 我相信merge asof 是最好的方法 然而 有两件事发生merge asof 不理想的 数字重复 数字丢失 以下代码是一个示例 df a pd Da
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 有人用过 Dabo 做过中型项目吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我们正处于一个新的 ERP 风格的客户端 服务器应用程序的开始阶段 该应用程序是作为 Python 富客户端开发的 我们目前正在评估 Dabo

随机推荐

  • 云孚科技受邀参加2023年大连数交会

    2023年7月6日至9日 由商务部 科技部 中国贸促会和辽宁省政府共同主办的2023中国国际数字和软件服务交易会 简称 数交会 在辽宁大连举行 云孚科技受中关村软件园孵化器邀请 与其他23家数字与软件服务企业组成北京展团共同参加本届数交会大
  • 代码中获取系统相关信息的函数

    1 GetModuleFileName 函数返回当前进程已加载可执行或DLL文件的完整路径名 以 0 终止 DWORD WINAPI GetModuleFileName HMODULE hModule 应用程序或DLL实例句柄 NULL则为
  • cmake指定编译器以及32位、64位版本

    概述 本文演示环境 win10 VS2017 1 指定变量值 咱们常用命令 cmake 在build目录下配置生成项目和解决方案 其实 这个命令还有其他用法 指定CMakeLists txt中的变量值 比如 fmt 库 的CMakeList
  • WinCC 中获取鼠标位置的应用

    热线支持的过程中有时会遇到一些客户提出要在 WinCC 项目运行时 在画面中捕捉到鼠标的坐标值 多年的热线支持养成的习惯总是会驱使我考虑一下用户要这个坐标值干嘛用呢 当然 问客户是最直接的 得到最多的回答就是希望获取这个坐标的目的在于 当在
  • 解决Python中sum函数出现的TypeError: unsupported operand type(s) for +: 'int' and 'list'错误问题

    当在Python中运行sum函数时 会出现 TypeError unsupported operand type s for int and list 这样的问题 代码如 print sum 1 2 3 4 5 5 会出现如下的错误 解决方
  • AI小白快上车!这是发往高薪职位的车!

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 本文由腾讯云AI中心 发表于云 社区专栏 AI到底有多火 看看下面这组数据 腾讯研究院 2017全球人工智能人才白皮书 报告中提到 现全球AI领域人才约30万 而市场对人才的需求在百
  • 【毕业设计 / 课程设计】 基于深度学习的人体动作姿势识别系统

    文章目录 0 项目说明 1 研究目的 2 研究方法 3 研究结论 4 目录 5 项目源码 0 项目说明 基于深度学习的人体动作姿势识别系统 提示 适合用于课程设计或毕业设计 工作量达标 源码开放 获取项目源码 https download
  • 常见的数据增强方式

    详见 Pytorch基础学习 第二章 Pytorch数据处理 Billie使劲学的博客 CSDN博客 pytorch 数据集处理
  • AI软件克隆你的声音,全球诈骗案件已屡次得逞!

    在2月28号刚于旧金山结束的RSA大会上 一家名为Pindrop的专门检测语音诈骗的初创公司再次向业内发出警告 网络诈骗份子已经开始借助AI软件克隆声音进行诈骗了 Pindrop的CEO 右 和CTO 左 图片来自网络 Pindrop的CE
  • Jupyter Notebook修改背景添加jupyterthemes后,输入‘jt -l‘,报错‘jt‘ 不是内部或外部命令,也不是可运行的程序

    目录 1 报错原因 2 继续操作 1 报错原因 jupyterthemes 装到了C Users bs AppData Roaming Python Python37 site packages中 然而 这个路径并不在环境变量的PATH变量
  • artipub点击“更新cookie状态“无任何反应

    作者 弗拉德 来源 弗拉德 公众号 fulade me artipub ArtiPub Article Publisher 的简称 意为 文章发布者 是一款开源的一文多发平台 可以帮助文章作者将编写好的文章自动发布到掘金 SegmentFa
  • jQuery的todolist案例实现

    想必大家都需要记录一些小事情 类似于记录生活 以后还能翻出来看看 本次就可以用jQuery来实现一下 对于本案例其实也不难 无非是一个增删查改加上本地存储缓存机制来实现的操作 下面就给出代码相关分析 相关样式资源可以私下找我 QQ35349
  • 如何杀掉其他人远程ssh的进程

    执行w 看当前远程的终端 执行pkill kill t pts 3 杀死pts 3的 ssh进程
  • VScode配置C/C++环境,MinGW,最新成功实例分享(win10)

    win10 VScode配置C语言 自己调试成功后 分享出来 首先下载VScode 这个十分简单 直接官网搜索最新的就行了 VScode下载官网VScode下载官网 然后安装 其中windows下支持C语言的编译 有两个好用的分别是MinG
  • 什么是Docker

    文章目录 一 什么是Docker 一 什么是Docker 微服务虽然具备各种各样的优势 但服务的拆分通用给部署带来了很大的麻烦 特别是一些大型项目组件较多 运行环境也较为复杂 部署时会碰到一些问题 依赖关系复杂 容易出现兼容性问题 分布式系
  • 简单使用matlab做回归分析、拟合分析

    简单使用matlab做回归分析 拟合分析 前言 一元线非线性回归 例子 多元线性回归 例子 多元线非线性回归 前言 这里是简单做一元非线性 及多元线性 一元 就是只有一个X 比如 y x 2 x 1 多元 就是多个X 比如 y x1 x2
  • Unity 小球在两点之间往返运动

    在Vectoer3类中有一个Lerp方法 可以让一个物体从一个点到另外一个点 如果要在 这里点加往返运动我们可以借助Mathf PingPong 这个方法 这个方法会从0 Lenght持续增加 达到最大值后 持续减小 然后到0 如此反复 每
  • 基于协同过滤算法实现选课推荐系统

    新版本教务管理系统 教务管理系统 选课功能 1 系统功能 1 用户账户管理 2 学生个人信息的查看与修改 3 学生的网上选课与课程的评分 4 教师个人信息的查看与修改 5 教师对学生课程评价结果的查看 6 管理员对学生信息与教师信息的查看与
  • 前端绘制地铁路线图

    前端绘制地铁路线图 前端可以使用多种技术绘制二维地图 以下是几种常见的方法 SVG SVG是一种基于XML的矢量图形格式 可以使用SVG元素绘制各种形状和路径 包括线 圆 多边形等 可以使用JavaScript库如D3 js来绘制SVG地图
  • 【推荐系统】{1} —— 基于用户的协同过滤算法

    协同过滤 英语 Collaborative Filtering 简称CF 简单来说是利用某兴趣相投 拥有共同经验之群体的喜好来推荐用户感兴趣的信息 个人透过合作的机制给予信息相当程度的回应 如评分 并记录下来以达到过滤的目的进而帮助别人筛选