BPR算法

article/2025/9/16 20:56:28

目录

什么是BPR算法

BPR算法简介

显示反馈与隐式反馈

矩阵分解的不足

BPR算法

符号定义

BPR算法解决方式

BPR算法两个基本假设

BPR算法推导

贝叶斯定理

BPR推导

BPR算法流程

BPR算法代码与结果

数据

BPR算法代码

BPR结果展示

什么是BPR算法

BPR算法简介

BPR(Bayesian Personalized Ranking),中文名为贝叶斯个性化排序,是推荐系统常用的一种算法。

显示反馈与隐式反馈

  • 显示反馈:用户明确表示对物品喜好的行为,如评分、评等级等;
  • 隐式反馈:不能明确反映用户喜好的行为,如浏览,点击等;

矩阵分解的不足

在隐式反馈的情况下,我们使用矩阵分解(MF)时,所收集到的数据均为正样本,而我们标记为零元素的样本分为两种情况:一种是该用户对该物品确实没有兴趣,一种是数据缺失。转换过程如上图所示。对于以上两种情况,我们使用矩阵分解算法时无法进行区别。

而在矩阵分解得到结果之后,常常将预测结果进行排序来为用户进行推荐。BPR算法则是直接排列出推荐物品的相对顺序,并没有预测出具体的评分。

BPR算法

符号定义

用户集U,物品集I,有过隐式反馈记录记作+,无隐式反馈记录记作?。

首先定义偏好关系\succ,如果用户在物品i和物品j中只对物品i产生了隐式反馈,则说明用户对物品i的喜爱程度大于物品j,则记为u_i\succ u_j。由以上易知,此关系满足完整性、传递性、反对称性。

BPR算法解决方式

  • 对于隐式反馈矩阵进行处理如果一个用户对物品i产生过隐式反馈行为(如:浏览)而对物品j没有产生过行为,则可以构建一个偏好对(u,i,j),如果一个用户对物品i和物品j都产生过隐式反馈行为,则无法构建偏好对。
  • 对每个用户构建其I\times I的偏好矩阵。

BPR算法两个基本假设

  • 每个用户之间的偏好行为相互独立,即用户u在商品i和j之间的偏好和其他用户无关。
  • 同一用户对不同物品的偏序相互独立,也就是用户u在商品i和j之间的偏好和其他的商品无关。

BPR算法推导

贝叶斯定理

通常,事件 A 在事件 B 发生的条件下与事件 B 在事件 A 发生的条件下,它们两者的概率并不相同,但是它们两者之间存在一定的相关性,并具有以下公式(称之为“贝叶斯公式”):

P(A|B)=\frac{P(B|A)P(A)}{P(B)}

BPR推导

根据贝叶斯公式,有

P(\theta |> u)=\frac{P(> u|\theta )P(\theta )}{P(> u)}

由于我们假设每一个用户的偏好与其他用户无关,所以对于每一个用户来说,P(> u)对该用户的所有物品一样,于是有以下关系:P(\theta |> u)\propto P(> u|\theta )P(\theta )。所以优化目标可分为两部分,左边的部分与数据集有关,右边部分P(\theta )与数据集无关。

  • 第二部分P(\theta )

P(\theta )与数据集无关,由于\theta未知,我们假设其服从均值为0,协方差为\lambda _\theta I的正态分布,即P(\theta )\sim N(0,\lambda _\theta I)。由以上可知,lnP(\theta )=\lambda \left \| \theta \right \|^{2}

  • 第一部分P(> u|\theta )

由于我们假设每一个用户喜好的独立性,并且每一个用户对所有物品喜好的独立性,所以有\prod P(> u|\theta )=\sigma (\bar{x}_{uij}(\theta ))

其中,\sigma (x)是sigmoid函数。为什么用sigmoid函数来代替:其实这里的代替可以选择其他的函数,不过式子需要满足BPR的完整性,反对称性和传递性和方便优化计算。

对于\bar{x}_{uij},满足\bar{x}_{uij}=\bar{x}_{ui}-\bar{x}_{uj}

第一部分优化为\prod P(> u|\theta )=\prod \sigma (\bar{x}_{ui}-\bar{x}_{uj})

  • 综上,最大化P(\theta |> u) 就转化成求解下式最大值:

最后,用梯度下降法进行求解,对\theta求导,有:

BPR算法流程

  • 随机化初始矩阵W,H;
  • 利用梯度下降法进行更新:

  • 若W、H收敛,则算法结束,否则进行上一步;
  • 计算排序分数\bar{x}_{ui}=w_u\cdot h_i

BPR算法代码与结果

数据

链接:https://pan.baidu.com/s/1FKYavzmCaTBzeQkQIoThIw 
提取码:xbyr

BPR算法代码

  • BPR_basic.py
# -*- coding: utf-8 -*-#引入以下Python库
import random
from collections import defaultdict
import numpy as np
from sklearn.metrics import roc_auc_score
import scores
'''
函数说明:BPR类(包含所需的各种参数)
'''
class BPR:user_count = 943#用户数item_count = 1682#项目数latent_factors = 20#k个主题,k数lr = 0.01#步长αreg = 0.01#参数λtrain_count = 10000#训练次数train_data_path = 'train.txt'#训练集test_data_path = 'test.txt'#测试集#U-I的大小size_u_i = user_count * item_count# 随机设定的U,V矩阵(即公式中的Wuk和Hik)矩阵U = np.random.rand(user_count, latent_factors) * 0.01V = np.random.rand(item_count, latent_factors) * 0.01biasV = np.random.rand(item_count) * 0.01#生成一个用户数*项目数大小的全0矩阵test_data = np.zeros((user_count, item_count))print("test_data_type",type(test_data))#生成一个一维的全0矩阵test = np.zeros(size_u_i)#再生成一个一维的全0矩阵predict_ = np.zeros(size_u_i)#通过文件路径,获取U-I数据def load_data(self, path):user_ratings = defaultdict(set)#输入文件路径pathwith open(path, 'r') as f:for line in f.readlines():u, i = line.split(" ")u = int(u)i = int(i)user_ratings[u].add(i)return user_ratings#输出字典user_ratings,为包含U-I的键值对#输出一个numpy.ndarray文件(n维数组)test_data,其中把含有反馈信息的数据置为1#通过文件路径,获取测试集数据 获取测试集的评分矩阵def load_test_data(self, path):file = open(path, 'r')#测试集文件路径pathfor line in file:line = line.split(' ')user = int(line[0])item = int(line[1])self.test_data[user - 1][item - 1] = 1#对训练集字典处理,更新分解后两个矩阵def train(self, user_ratings_train):for user in range(self.user_count):# 随机获取一个用户u = random.randint(1, self.user_count) #找到一个user# 训练集和测试集不是全都一样的,比如train有948,而test最大为943if u not in user_ratings_train.keys():continue# 从用户的U-I中随机选取1个Itemi = random.sample(user_ratings_train[u], 1)[0] #找到一个item,被评分# 随机选取一个用户u没有评分的项目j = random.randint(1, self.item_count)while j in user_ratings_train[u]:j = random.randint(1, self.item_count) #找到一个item,没有被评分#构成一个三元组(uesr,item_have_score,item_no_score)# python中的取值从0开始u = u - 1i = i - 1j = j - 1#BPRr_ui = np.dot(self.U[u], self.V[i].T) + self.biasV[i]r_uj = np.dot(self.U[u], self.V[j].T) + self.biasV[j]r_uij = r_ui - r_ujloss_func = -1.0 / (1 + np.exp(r_uij))# 更新2个矩阵self.U[u] += -self.lr * (loss_func * (self.V[i] - self.V[j]) + self.reg * self.U[u])self.V[i] += -self.lr * (loss_func * self.U[u] + self.reg * self.V[i])self.V[j] += -self.lr * (loss_func * (-self.U[u]) + self.reg * self.V[j])# 更新偏置项self.biasV[i] += -self.lr * (loss_func + self.reg * self.biasV[i])self.biasV[j] += -self.lr * (-loss_func + self.reg * self.biasV[j])#得到预测矩阵/评分矩阵predictdef predict(self, user, item):predict = np.mat(user) * np.mat(item.T)return predict#主函数def main(self):#获取U-I的{1:{2,5,1,2}....}数据user_ratings_train = self.load_data(self.train_data_path)#获取测试集的评分矩阵self.load_test_data(self.test_data_path)for u in range(self.user_count):for item in range(self.item_count):if int(self.test_data[u][item]) == 1:self.test[u * self.item_count + item] = 1else:self.test[u * self.item_count + item] = 0#训练for i in range(self.train_count):self.train(user_ratings_train)  #训练10000次完成predict_matrix = self.predict(self.U, self.V) #将训练完成的矩阵內积# 预测self.predict_ = predict_matrix.getA().reshape(-1)  #.getA()将自身矩阵变量转化为ndarray类型的变量print("predict_new",self.predict_)self.predict_ = pre_handel(user_ratings_train, self.predict_, self.item_count)auc_score = roc_auc_score(self.test, self.predict_)print('AUC:', auc_score)# Top-K evaluationscores.topK_scores(self.test, self.predict_, 5, self.user_count, self.item_count)#对结果进行修正,即用户已经产生交互的用户项目进行剔除,只保留没有产生用户项目的交互的数据
def pre_handel(set, predict, item_count):#确保推荐不是训练集中的正样本for u in set.keys():for j in set[u]:predict[(u - 1) * item_count + j - 1] = 0return predictif __name__ == '__main__':#调用类的主函数bpr = BPR()bpr.main()
  • scores.py 
# -*- coding: utf-8 -*-#引入heapq、numpy、math库
import heapq
import numpy as np
import math
#计算项目top_K分数
def topK_scores(test, predict, topk, user_count, item_count):PrecisionSum = np.zeros(topk+1)RecallSum = np.zeros(topk+1)F1Sum = np.zeros(topk+1)NDCGSum = np.zeros(topk+1)OneCallSum = np.zeros(topk+1)DCGbest = np.zeros(topk+1)MRRSum = 0MAPSum = 0total_test_data_count = 0for k in range(1, topk+1):DCGbest[k] = DCGbest[k - 1]DCGbest[k] += 1.0 / math.log(k + 1)for i in range(user_count):user_test = []user_predict = []test_data_size = 0for j in range(item_count):if test[i * item_count + j] == 1.0:test_data_size += 1user_test.append(test[i * item_count + j])user_predict.append(predict[i * item_count + j])if test_data_size == 0:continueelse:total_test_data_count += 1predict_max_num_index_list = map(user_predict.index, heapq.nlargest(topk, user_predict))predict_max_num_index_list = list(predict_max_num_index_list)hit_sum = 0DCG = np.zeros(topk + 1)DCGbest2 = np.zeros(topk + 1)for k in range(1, topk + 1):DCG[k] = DCG[k - 1]item_id = predict_max_num_index_list[k - 1]if user_test[item_id] == 1:hit_sum += 1DCG[k] += 1 / math.log(k + 1)# precision, recall, F1, 1-callprec = float(hit_sum / k)rec = float(hit_sum / test_data_size)f1 = 0.0if prec + rec > 0:f1 = 2 * prec * rec / (prec + rec)PrecisionSum[k] += float(prec)RecallSum[k] += float(rec)F1Sum[k] += float(f1)if test_data_size >= k:DCGbest2[k] = DCGbest[k]else:DCGbest2[k] = DCGbest2[k-1]NDCGSum[k] += DCG[k] / DCGbest2[k]if hit_sum > 0:OneCallSum[k] += 1else:OneCallSum[k] += 0# MRRp = 1for mrr_iter in predict_max_num_index_list:if user_test[mrr_iter] == 1:breakp += 1MRRSum += 1 / float(p)# MAPp = 1AP = 0.0hit_before = 0for mrr_iter in predict_max_num_index_list:if user_test[mrr_iter] == 1:AP += 1 / float(p) * (hit_before + 1)hit_before += 1p += 1MAPSum += AP / test_data_sizeprint('MAP:', MAPSum / total_test_data_count)print('MRR:', MRRSum / total_test_data_count)print('Prec@5:', PrecisionSum[4] / total_test_data_count)print('Rec@5:', RecallSum[4] / total_test_data_count)print('F1@5:', F1Sum[4] / total_test_data_count)print('NDCG@5:', NDCGSum[4] / total_test_data_count)print('1-call@5:', OneCallSum[4] / total_test_data_count)return

BPR结果展示


http://chatgpt.dhexx.cn/article/AqtcH92p.shtml

相关文章

基于物理的渲染技术(PBR)系列一

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术…

[引擎开发] PBR材质的原理

[本文大纲] 基础概念篇 引入 光线与介质的作用 光线的传播路径 体积散射和表面光照 光线和介质外观 微平面理论 概念介绍 中间向量 能量守恒定律 微平面理论的不足 光照计算 半球积分 …

PBR材质基础概念,限制及未来发展

最近几年图形学社区对PBR的关注非常高,也许是由于Disney以及一些游戏引擎大厂的助推,也许是因为它可以被轻松集成进实时渲染的游戏引擎当中,也许是因为许多人发现现在只需要调几个参数就能实现具有非常精细细节的表面着色了。反正现在网络上随…

PBR渲染(一)——PBR理论基础

PBR基础框架 PBR理论基础PBR基础框架 1.PBR理论基础 BSDF(双向散射表面分布函数) 对于一般的基于物理的表面材质来说,使用第一项BSSRDF双向散射表面反射分布函数,其简化后的重点就是BRDF双向反射率分布函数,忽略了复…

Unity ShaderGraph没有PBR Graph的解决方法

1.创建光照Shader Graph 2.打开Shader Graph界面 Fragment选项卡上右击——Add Block Note——添加Alpha和Alpha Clip Threshold两个属性 可以看到此时这两个属性是灰色的,并不生效,是因为未启用Alpha Clipping 3.Graph Inspector选项卡中,勾…

在3ds max中,什么是PBR材质?

PBR是Physically-Based Rendering(基于物理的渲染)的简称。 PBR材质是一种基于物理的渲染材质,可提供灯光与曲面交互方式的精确表示。注: 仅当活动渲染器支持时,该材质才会显示在“材质/贴图浏览器”中。 在3ds max中PBR材质分为…

理解PBR:从原理到实现(上)

PBR 从离线渲染进入游戏引擎 CSDN 博客的公式排版有问题,可以看我的 GitHub Page:https://neil3d.github.io/unreal/pbr-theory.html 基于物理的渲染,即 PBR,Physically Based Rendering,这个技术名词最早是有马特法尔…

什么是PBR

PBR就是基于物理的渲染。 首先得介绍光照模型。光照模型是一种数学模型,也就是一种算法。这些算法用于计算机模拟物体在光照下的表现,具体就是 计算物体某一点处的光强。 这些模型从理论而言分为两类。 基于物理理论的和 基于感知经验的。 PBR就是基于…

BPR

BPB模型概念 BPR(Bayesian Personalized Ranking)推荐模型是基于贝叶斯后验优化的个性化排序算法。从user-iem矩阵训练出多个矩阵,而且一个矩阵表示一个用户的item偏好情况来获得用对多个item的偏好关系的推荐系统。本身不优化用户对物品的评分,只是借由…

两种不同的PBR工作流介绍

本文介绍两种常用的PBR材质工作流:金属/粗糙度工作流(Metal/Roughness)和镜面反射/光泽度工作流(Specular/Glossiness)。这两种工作流都可以用来制作一个支持PBR的材质,并用PBR渲染出逼真的效果&#xff0c…

4.3 PBR

1. 实验目的 熟悉PBR的应用场景掌握PBR的配置方法2. 实验拓扑 PBR实验拓扑如图4-8所示: 图4-8:PBR 3. 实验步骤 (1) IP地址的配置 R1的配置 <Huawei>system-view

PBR渲染(二)——PBR皮肤渲染

PBR皮肤渲染 在PBR基础框架的基础上实现皮肤的渲染&#xff0c;要根据皮肤的渲染特性来对基础框架进行扩充和修改&#xff0c;从而实现真实感的PBR皮肤渲染。皮肤一般具有以下渲染特性&#xff1a; 1.次表面散射&#xff08;SSS&#xff09; 2.BRDF高光&#xff08;Specular …

PBR 基础知识干货总结

&#xff08;1&#xff09;什么是PBR&#xff1f; 基于物理的渲染过程。 PBR是一种着色和渲染技术&#xff0c;用于更精确的描述光如何与物体表面互动。 PBR的优势&#xff1a; &#xff08;1&#xff09;方法论和算法基于精确的计算公式&#xff0c;免除创作表面的猜想过程。 …

PBR与Blinnphong解读

我们做光栅化模式的渲染都了解有两种比较常用的渲染方式&#xff0c;一个是blinnphong的渲染&#xff0c;一个是pbr的渲染。 blinnphong&#xff1a; blinnphong的渲染模式更多的是一种经验值模拟光照对物体的效果。所以他不是一个正确的能量守恒的渲染方式。 blinnphong的渲…

【基于物理的渲染(PBR)白皮书】(一) 开篇:PBR核心知识体系总结与概览

本文由浅墨_毛星云 出品&#xff0c;首发于知乎专栏&#xff0c;转载请注明出处 文章链接&#xff1a; https://zhuanlan.zhihu.com/p/53086060 先放出PBR知识体系的架构图&#xff1a; 图很大&#xff0c;建议下载到本地放大查看。原图下载地址&#xff1a; https://raw.gi…

什么是PBR?

一、什么是PBR&#xff1f; 基于物理渲染以前的渲染是在模仿灯光的外观现在是在模仿光的实际行为试图形看起来更真实 二、PBR组成部分 灯光属性&#xff1a;直接照明、间接照明、直接高光、间接高光、阴影、环境光闭塞表面属性&#xff1a;基础色、法线、高光、粗糙度、金属度…

PBR流程介绍和模型规范

&#xff08;1&#xff09;基本流程&#xff1a; &#xff08;1&#xff09;制作中模&#xff1a; 基础模型&#xff1a; 指的是中模&#xff01;&#xff01; 中模导出为.obj 格式&#xff08;跟.fbx格式相比&#xff1a;不会出现模型大小的缩放&#xff09; 高模&#xff1a…

PBR材质:基本原理和简单制作

概要&#xff1a;介绍PBR材质的基本原理以及制作一个简单的PBR材质 参考资料&#xff1a;BASIC THEORY OF PHYSICALLY-BASED RENDERING 如有问题&#xff0c;多多指正。 侵删。 1.PBR是什么&#xff0c;光线的基本原理。 PBR即Physically-based rendering&#xff0c;基于物理…

什么是PBR?pbr入门基础干货

&#xff08;1&#xff09;什么是PBR&#xff1f; 基于物理的渲染过程。 PBR是一种着色和渲染技术&#xff0c;用于更精确的描述光如何与物体表面互动。 PBR的优势&#xff1a; &#xff08;1&#xff09;方法论和算法基于精确的计算公式&#xff0c;免除创作表面的猜想过程…

PBR——概述、基于物理的材质

PBR概述 PBR&#xff0c;即Physically Based Rendering&#xff0c;主要分为基于物理的材质、基于物理的光照和基于物理的相机三个部分&#xff0c;目前来说对大家最为所熟知的是基于物理的材质部分。本文围绕基于物理的材质进行相关介绍。 什么是PBR 其实最早听说PBR这玩意…