打造个性化观影盛宴:对实时多兴趣召回的探索

news2024/10/1 16:38:54

包括 Tubi 在内的广告型点播流媒体服务,正在成为免费在线消费娱乐的重要组成部分。Tubi 拥有一个囊括电视剧、电影、体育和娱乐直播频道的海量视频内容库;同时,Tubi 为观众提供个性化的视频推荐,帮助观众快速找到想看的视频内容,这是确保用户体验的关键因素。然而,Tubi 的数百万月度活跃用户来自全球众多国家,在海量视频内容库中为用户挑选满足其主流或小众多样化需求的视频内容是极具挑战的。​

Tubi 致力于为用户提供全方位的个性化体验,从用户观看的视频内容,到电影电视海报的选择,甚至在播放、详情展示等方面也会进行个性化处理。Tubi 运行着 70 多个机器学习模型以响应用户请求来构建主页。这些不同的模型分别用于新老用户,对用户相关的视频内容、主页上不同类别视频的集合以及自动播放的内容进行排序。

本文着重分享我们在召回方面的探索,以及这一过程中我们所做的各种设计选择。

召回

大多数现代推荐系统是基于两阶段推荐过程,第一阶段可将候选空间从数百万减少至用户可能感兴趣的较少数量的相关候选集,推荐系统的第二阶段是生成候选集的最终排名。

召回是 Tubi 推荐系统的关键组成部分,因其作为一个轻量的阶段,可减少候选集大小,从而在延迟上为复杂的排序模型提供更大的空间。我们往期已完成的实验表明,召回阶段的效率不仅体现于用户参与度和体验方面的改善,还将减少计算和存储成本。

图一:典型的两阶段推荐流程

Tubi 的召回探索

Tubi 对个性化的探索开始于利用天级别的离线任务为每个用户计算内容排序。起初,Tubi 的内容和用户群体都较小,因此我们可以做到为所有用户对整个内容目录进行排名。此外,构建实时推荐的基础设施需要投入一定的成本。

图二:2016 年 Tubi 首页

随着 Tubi 越来越受欢迎,日活跃用户和视频数量也在持续增长,为所有用户进行整个内容目录的排序需要占用大量计算资源。为降低计算和数据同步成本,我们采取的方式是减少存储每个用户的排名结果;这种方式在降低计算和数据同步成本方面确实有帮助,但牺牲了用户的个性化体验。

我们便从这里开始了对召回的探索。我们从一些简单的流行度指标入手,减少待排序的候选集;流行度可以基于国家、语言、类别和外部评估等标准来衡量。这样的召回方式特别适用于新用户,因为我们不熟悉其喜好,对他们的视频内容无法实现和对老用户一样的个性化。然而,对于老用户来说,这只是一个可用的初步筛选方案,因这一方案缺乏个性化,也加剧了流行度偏差。

基于 Embedding 的召回

与我们遇到的大多数其他问题一样,在这一过程中我们意识到个性化是关键。我们首先采用了协同过滤技术,根据用户过往的观看行为,利用”群体智慧”找到其可能想要观看的相关内容。

矩阵分解是实现协同过滤的传统方法之一,可以将 User Item 交互矩阵降维到低秩空间。User-Item 向量的内积就是用户对某一视频的偏好得分,这一内积也可以作为一个可用的初步召回方案。

由于每天进入系统的用户数量增加,我们在构建召回时遇到了如下问题:

1. 用于召回的用户向量需要大量存储空间

2. 并非所有用户的 User 向量质量都是可靠的,这是因为我们只采样部分用户用于训练模型。为此,我们转而依赖于 Item 向量进行召回,并选择一个用户表示(例如观看历史记录)来生成召回候选集。

与此同时,深度学习在计算机视觉、自然语言处理和语音识别等领域取得了巨大的进展,其中非常重要的一项技术是表示学习,也就是 Embedding 的生成。

Embedding 是基于神经网络,用于表征文本或者类别数据的稠密数值向量;它的功能强大,可以捕捉到对象之间关系的本质,并可用于下游应用。通过 Tubi 众多合作伙伴和非合作伙伴(如 IMDB、Gracenote、RottenTomatoes 和维基百科),我们可以获取丰富的元数据,用于生成各种 Embedding。

图三:与每个视频内容相关的元数据

我们创建了 Spock 平台以更好地理解视频内容,该平台生成从 Doc2Vec 到 BERT 的各种 Embedding。请参阅往期技术博客了解详细信息。

如何生成召回候选项?

生成召回候选项的最快方法之一是查看用户过往喜欢观看的视频内容,生成更多类似的候选项;利用 Embedding,基于用户过往的观看历史来生成最近邻。后文我们将分享期间遇到的各种选择及现状。

版本 1:对 Embeddings 进行平均化

我们通过对用户观看历史的 Embeddings 进行平均,生成了用户 Embedding。平均化所带来的问题之一是信息丢失致使我们最终可能得到完全不相关的结果。例如,如果一个用户同时喜欢观看恐怖片和喜剧片,平均化可能会让结果既不落于恐怖片也不落于喜剧片类别。平均化的优势则是能得到简洁的用户表示,并且在计算最近邻时只需要考虑这一个平均后的向量表示。这样的召回方式意味着获取用户 Embeeding 的最近邻。

图四:将观看历史中的内容 Embedding 进行平均,生成用户 Embedding

版本 2:观看历史中每个视频的最近邻

除了平均化 Embedding,还可以对观看历史中的每个视频生成最近邻。这种做法的好处是每个视频内容都可以有自己的最近邻,坏处则是离线计算召回候选集和数据同步的任务将变得过于繁重,提取视频和计算检索的离线工作将变得过多,并且这一情况随着 Tubi 的增长也将变得更加严重。

图五:计算观看历史中每个视频的最近邻,而非对 Embedding 进行平均化

版本 3: 多模态用户喜好

我们在观察用户的观看行为时发现了一个十分关键的点,那就是用户的观看行为呈现聚类模式,如图六所示。受 Pal 等人在 PinnerSage 中想法的启发,我们决定对用户的观看行为进行聚类,以得到一种简洁的、基于中心点的用户表示形式。

图六:某一用户观看行为的聚类

中心点能抓住聚类的特征,是可以代表这个聚类的一个聚类成员。正如这篇文章所提到的,使用中心点是表示聚类的一个更省钱的方式,因其无需像质心那样存储 Embedding,对异常值也不太敏感。

我们使用层级聚类来生成每个用户观看历史的聚类,并基于此来计算它们的最近邻。实验结果显示,这种方式显著提升了用户观看,同时还降低了数据同步成本。

版本 4:实时

至此,我们已经讨论了在捕捉用户多模态喜好方面的创新实践,但此时整个系统依然是以 batch 的模式运行的。随着用户、内容和 Embedding 数量的增加,每日需要同步的召回候选集数量很快就难以应对了。为解决这一问题,我们实现了实时排名和计算最近邻。为此,我们基于 FAISS 和 HSNW 技术搭建了一个内部系统,实现了向实时的迁移,这一过程节省了大量非必要的计算和存储成本。

版本 5:基于上下文的探索与采样

一旦我们完成了每个用户的聚类,就可以计算聚类的重要性,可查看这篇文章了解更多内容。聚类重要性可以很好地捕捉不同聚类在规模大小、最近观看内容和观看时长方面的不同特点,有助于我们对每个用户请求进行探索和采样,以便推荐上下文相关的内容,同时也使推荐结果是动态变化的。

版本 6:来接受挑战吧!

一旦实现了实时排名和最近邻计算,我们便可以做出更多酷炫的尝试了,例如自适应实时聚类、使用更多的用户反馈信号以及基于不同标准的聚类重要性。变革是当今时代的主题,我们正在这样做,甚至还会做更多。

作者:Jaya Kawale, Tubi Vice President of Engineering, Machine Learning

译者:Honghong Zhao, Senior Engineer, Machine Learning

校对:Shengwu Yang, Director, Machine Learning


如果你对类似项目感兴趣,欢迎加入 Tubi!

  • 查看热招岗位
  • 关注微信公众号

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零实战SLAM-第二课(SLAM中的基础数学)

空间数据的表达方式:点和向量两种形式。 向量的内积,也叫做点乘,是逐点相乘后累加,最终结果是一个标量,物理意义是一个向量在另一个向量上的投影。 外积,也叫做叉乘,两个向量拼起来成&#xff0…

vue二进制下载

封装axios,/api/request import axios from axios import store from /store import Vue from vue import { Message, MessageBox } from element-uiimport { getToken } from /utils/authaxios.defaults.headers[Content-Type] application/json;charsetutf-8 co…

同一局域网共享一个打印机方法

文章目录 需求描述设备连接情况配置网络凭证 需求描述 pc2想直接打印,而不是每次存到u盘,再拿到pc1,打印,实现本机打印 设备连接情况 配置 (1)pc1设置 ①共享打印机操作 控制面板——>设备和打印机—…

HC32L110B6芯片测试

到货之后,直观上感觉的确很小,小包装盒里面还装了说明书。 下载器单独在一个盒里面,但是这个T-U2T没用上,还是用的STLINK。 开发之前先去网上找了一些别人遇到的坑,的确不少。 涉及的方面也是挺全的,供电、…

1. 如何爬取自己的CSDN博客文章列表(获取列表)(博客列表)(手动+python代码方式)

文章目录 写在最前步骤打开chrome浏览器,登录网页按pagedown一直往下刷呀刷呀刷,直到把自己所有的博文刷出来然后我们按F12,点击选取元素按钮然后随便点一篇博文,产生如下所示代码然后往上翻,找到头,复制然…

DC-9靶机(端口敲门服务Knockd)

DC-9靶机地址 信息收集 主机发现 靶机MAC:00:0C:29:5A:C1:F4 arp-scan -l端口扫描 nmap -A -p- 192.168.80.142访问80端口 目录爆破 dirsearch -u 192.168.80.139 -i 200点击页面上的四个标签,发现 有个搜索 框,有个登录框 先用bp抓个包…

atxserver2环境搭建

1. 卸载python3.11.4版本 $sudo rm -rf /Library/Frameworks/Python.framework/Versions/3.11/ $sudo rm -rf /Applications/Python\ 3.11/ 第三步:删除指向python的链接 cd /usr/local/bin/ ls -l /usr/local/bin | grep /Library/Frameworks/Python.framework/…

利用logstash将graylog日志传输到kafka中

1.graylog配置输出 在System-outputs,选择GELF Output,填写如下内容,其它选项默认 在要输出的Stream中,选择Manage Outputs 选择GELF Output,右边选择刚才创建好的test。 2.安装logstash,作为中间临时…

Vue 整合 Element UI 、路由嵌套和参数传递(五)

一、整合 Element UI 1.1 工程初始化 使用管理员的模式进入 cmd 的命令行模式,创建一个名为 hello-vue 的工程,命令为: # 1、目录切换 cd F:\idea_home\vue# 2、项目的初始化,记得一路的 no vue init webpack hello-vue 1.2 安装…

记录一次使用python调用java代码

Python调用Java代码的主要原理是通过使用Java虚拟机(JVM)和相关的库/工具实现的。 在Python中,可以使用以下几种方式来调用Java代码: 使用subprocess模块:可以通过subprocess模块来启动一个子进程,并在子进…

OpenGL纹理

纹理采样器----纹理坐标 只有纹理坐标,纹理没有作用。 纹理坐标是在顶点着色器中设置,需要传入片段着色器,在片段着色器中需要定义纹理采样器。 然后调用texture函数利用采样器和纹理坐标对纹理进行采样。 我们使用GLSL内建的texture函数…

大模型落地金融业,想象力在哪?

金融大模型的难点在于,能否在产业中扎得更深;其颠覆性也更建立在,纵深到产业中去,赋能金融行业的长尾场景发展,以及重拾“金融信任”。 作者|思杭 编辑|皮爷 出品|产业家 “从经济角度讲,整个金融业…

界面设计用什么工具好?还不知道这5个吗?

无论是在APP设计,还是网站设计中,界面设计都是非常重要的,今天本文将为大家推荐5个优质的界面设计软件,一起来看看吧! 1、即时设计 即时设计是新一代界面设计软件,它不仅为设计师提供了精细的矢量编辑功能…

纯C#使用Visionpro工具1

各个工具的程序集名称 一般分类 一般情况是去掉Tool和Cog就是命名空间,如CogBlobTool对应于Cognex.Visionpro.Blob 也有特殊情况 忘了怎么办 可以借用ToolBlock引入工具后打开高级脚本查看 了解工具类和对象

过河卒(c++题解)

题目描述 棋盘上 A 点有一个过河卒,需要走到目标 B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。 棋盘用坐标表示&#xff…

【Tool】虚拟机安装与调试与设置与主机共享文件

前言 安装了vm17,实现了与主机文件共享, 步骤 下载虚拟机(试用版) Download VMware Workstation Pro 双击安装 暂不激活或者 使用如下激活码 KRNJX-22GXY-HCW46-MWYHY-YWRDB RDHTN-YFFKY-8YVR7-Q996Y-K74X3 N2XRH-GCH84-MV…

Linux系统上多文件C程序的编译与调试

一、先建立一个头文件add.h 通过vi创建一个add.h,并进行编写该文件,用来存放求和函数add()的声明: 二、建立一个add.c文件 通过vi创建一个add.c文件,并进行编写,用来存放求和函数add()的实现: 三、建立一…

写给 Android 应用工程师的 Binder 原理剖析

一. 前言 这篇文章我酝酿了很久,参考了很多学习文档,读了很多源码,却依旧不敢下笔。生怕自己理解上还有偏差,对大家造成误解,贻笑大方。又怕自己理解不够透彻,无法用清晰直白的文字准确的表达出 Binder 的…

构建之法 - 软件工程实践教学:一线教师的13问

福州大学单红老师的软工课程总结 2020春,不一样的学期不一样的软工实践 单红⽼师在总结中,提出了13条疑惑,《构建之法》的作者邹欣⽼师就单红⽼师提出的每⼀条疑惑,给出了⾃⼰的思考,与他进⾏探讨交流。欢迎你也来参与…

怎么系统的学习机器学习、深度学习?当然是看书了

目录 前言 内容简介 学完本书,你将能够 作者简介 本书目录 京东自购链接 前言 近年来,机器学习方法凭借其理解海量数据和自主决策的能力,已在医疗保健、 机器人、生物学、物理学、大众消费和互联网服务等行业得到了广泛的应用。自从Ale…