tech share
  • tech-share
  • Engineering
    • 登录鉴权
    • SSR 页面路由
    • npm 版本号
    • 缓存
    • 数据库容灾
    • 动态效果导出 gif
    • Chrome-devtools
    • C 端 H5 性能优化
    • Docker
    • Monorepo 最佳实践
    • 技术架构演化
    • 项目规范最佳实践
    • snowpack
    • 静态资源重试
    • 前端页面渲染分析
    • Git
    • 前端重构
    • 微前端
    • 项目依赖分析
    • 前端监控原理
    • webpack
    • BS 架构与 CS 架构
    • HTTPS
    • package-lock.json 生成逻辑
    • SVN(Subversion)
    • 数据库分类
    • gulp
    • 前端架构
    • Bundle & Bundless
    • 控制反转 IoC
  • JavaScript
    • Javascript 性能
    • JavaScript 原型(2) - 原型与原型链
    • JavaScript 原型(1) - 构造函数
    • JavaScript - Promise
    • ES6 解构赋值
    • 前端离线化
    • Proxy
    • Object.defineProperty()简介
    • TypeScript
  • MachineLearning
    • GAN生成对抗网络
    • 虚拟对抗训练
    • 深度度量学习
    • 原型网络
    • PyTorch优化器
    • 隐马尔可夫模型2
    • Shapley Value 算法
    • Embarassingly Autoencoder算法
    • AutoRec算法及其后续发展
    • 深度学习常用激活函数
    • 序列预测ConvTran算法
    • 联邦学习
    • 深度学习推荐系统算法整理
    • 隐马尔可夫模型
    • 黎曼优化方法
    • FM算法
    • 机器学习常见评价指标
    • VAE算法
    • Adam优化器详解
    • Transformer算法
    • Self-attention 推荐算法
    • CNN 卷积神经网络
    • 图嵌入
    • 集成学习算法
    • RecBole开源框架
    • NCE-PLRec
    • 深度学习初始化方法
    • RNN循环神经网络
    • PyTorch数据处理
    • PyTorch安装和基本操作
    • XGBoost算法
    • NCF算法与简单MF的对比
    • 计算最佳传输
  • CSS
    • 什么是BFC
    • 纯CSS实现可拖动布局
    • 滚动穿透解决方案
  • React
    • React 生命周期
    • React Ref
    • React Hooks
    • SWR
    • React 数据流
    • React 函数式组件和类组件的区别
  • 可视化
    • OffscreenCanvas
    • Echarts 平滑曲线端点为什么不平滑
    • 颜色空间
    • 词云布局解析
    • 3D 数学基础
    • Canvas 图片处理
    • GLGL ES
    • WebGL 中绘制直线
    • Graphics API
    • 现代计算机图形学基础
    • Canvas 灰度
  • Vue
    • Vue2.x全局挂载整理
    • Vue2.6.x源码阅读
      • Vue2.6.x源码阅读 - 2.目录结构分析
      • Vue2.6.x源码阅读 - 4.源码阅读-platform
      • Vue2.6.x源码阅读 - 1.准备工作
      • Vue2.6.x源码阅读 - 5.源码阅读-core-Vue构造函数
      • Vue2.6.x源码阅读 - 7.源码阅读-core-响应式原理
      • Vue2.6.x源码阅读 - 3.源码阅读-shared
      • Vue2.6.x源码阅读 - 6.源码阅读-core-组件挂载
    • Vue + TypeScript Web应用实践
    • Vue2.x指令
    • nextTick()的使用
    • vue-cli2.x 的使用与项目结构分析
    • Vue响应式原理及总结
    • VueX的使用
    • Electron-Vue + Python 桌面应用实践
    • Vite
    • Vue组件通信整理
    • 记录一个问题的探索过程
  • Linux
    • memcg
  • GameDev
    • 游戏中的几种投影视图
    • 从零开始写软渲染器06
    • 从零开始写软渲染器05
    • 从零开始写软渲染器04
    • 从零开始写软渲染器03
    • 从零开始写软渲染器02
    • 从零开始写软渲染器01
    • 从零开始写软渲染器00
    • 现代游戏常用的几种寻路方案(一)
  • Node
    • NPM Dependency
    • Node 优势
    • Node Stream
    • Node 模块系统
  • HTML
    • html5语义与结构元素
  • 跨端
    • Flutter 介绍
  • Golang
    • Golang 基础
  • AR
    • SceneKit
由 GitBook 提供支持
在本页
  • 背景知识
  • NCE算法
  • 代码实现

这有帮助吗?

  1. MachineLearning

NCE-PLRec

上一页RecBole开源框架下一页深度学习初始化方法

最后更新于4年前

这有帮助吗?

NCE是自然语言处理中的一种做法,全称是Noise Constractive estimation。这个算法将类别数众多的自然语言多分类问题,转化成一种二分类的训练。

原本的算法是将上下文作为输入,输出该位置单词的编号,这样做需要在数万词的词汇表中通过多分类寻找到解,一般是非常困难的。而NCE采用负采样的方式,人为的选择一些错误的词与正确的词进行比较,使得模型可以分析出对应位置正确的词和错误词的区分规律。

NCE_PLRec就是一个采用了类似的思想解决推荐系统问题的算法,不过个人认为类似的做负采样并进行pairwise采样的办法在推荐领域并不鲜见,该文章的新颖之处在于对训练过程的优化。全文见

背景知识

NCE-PLREC主要是对推荐系统基本的算法和NCE算法的结合。

文章主要利用的是两种算法:

一是MF,即通过矩阵分解的方法将评分矩阵分解成用户和物品的特征向量,再用点乘的方式对矩阵进行重构

二是SLIM,即离散线性推荐方法。这种方法主要通过训练一个item相似度矩阵的方式对输入的评分矩阵进行修正。

其中r是评分矩阵,w是表示需要学习的相似度矩阵,通过这种方式可以通过其他已经有评分的item对无评分的item进行填补。

为了提高SLIM的性能,PLRec被提出。其中运用了基本的MF方法,如pureSVD产生item的特征向量。然后将这个embedding放入SLIM的目标公式中,从而进一步对物品的相似度做出更准确的衡量。

基于PLRec,作者主要提出的点在于其依赖于SVD的矩阵分解,存在较大的偏差,受物品流行度的影响非常严重。因此引入NCE生成更好的item embeddings,之后还是用一般的PLRec进行预测。

NCE算法

上节已经提到,NCE只用于产生去噪后的评分矩阵。此处NCE实际上是建立一个对于某个rating是否是噪声的分类模型。

对于每个评分点(对应一个用户、一个物品)来说,如果用sigmoid进行二分类,同时用交叉熵函数表示损失,损失函数表示如下。

其中j'是负采样出的用户i在训练集中没有点过的某个item。

将这个公式扩展到评分矩阵的全集上,表示如下:

对其中l的部分求导可以直接解出该损失函数的最优解为:

上式只针对在训练集中观测到的评分,对于未评分的那些点直接设置为0即可,至此就得到了经过NCE去噪的评分矩阵D。

基于D矩阵,其实已经可以通过SVD进行预测。此处作者添加了一些正则化,同时将D分解得到的item embedding重新和原始矩阵相乘后得到user embedding。

最终将这些结果带入到PLRec的close-form解中。整体算法如下所示:

类似的close-form解法其实在之前EASE中就有涉及,在此就不多做推导。

代码实现

代码实现的核心在于产生矩阵D,原作者是用numpy配合cupy实现在gpu上运算,笔者这里通过PyTorch进行复现。

def get_pmi_matrix_gpu(matrix, root):
    import torch
    rows, cols = matrix.shape
    item_rated = matrix.sum(dim=0)
    pmi_matrix = []
    nnz = matrix.nnz
    for i in tqdm(range(rows)):
        row_index, col_index = matrix[i].nonzero()
        if len(row_index) > 0:
            values = item_rated[:, col_index].squeeze()
            values = torch.max(torch.log(rows/torch.pow(values, root)), 0)[0]
            pmi_matrix.append(sparse.coo_matrix((values.numpy(), (row_index, col_index)), shape=(1, cols)))
        else:
            pmi_matrix.append(sparse.coo_matrix((1, cols)))
    return sparse.vstack(pmi_matrix)
Noise Contrastive Estimation for One-Class Collaborative Filtering
SLIM
PLRec
NCE_pointwise
NCE_all
NCE_optimal
NCE-PLRec