草庐IT

快手:通过强化学习提升用户留存

机器之心 2023-11-07 原文

短视频推荐系统的核心目标是通过提升用户留存,牵引 DAU 增长。因此留存是各APP的核心业务优化指标之一。然而留存是用户和系统多次交互后的长期反馈,很难分解到单个 item 或者单个 list,因此传统的 point-wise 和 list-wise 模型难以直接优化留存。

强化学习(RL)方法通过和环境交互的方式优化长期奖励,适合直接优化用户留存。该工作将留存优化问题建模成一个无穷视野请求粒度的马尔科夫决策过程(MDP),用户每次请求推荐系统决策一个动作(action),用于聚合多个不同的短期反馈预估(观看时长、点赞、关注、评论、转发等)的排序模型打分。该工作目标是学习策略(policy),最小化用户多个会话的累计时间间隔,提升 App 打开频次进而提升用户留存。

然而由于留存信号的特性,现有 RL 算法直接应用存在以下挑战:1)不确定性:留存信号不只由推荐算法决定,还受到许多外部因素干扰;2)偏差:留存信号在不同时间段、不同活跃度用户群体存在偏差;3)不稳定性:与游戏环境立即返回奖励不同,留存信号通常在数小时至几天返回,这会导致 RL 算法在线训练的不稳定问题。

该工作提出 Reinforcement Learning for User Retention algorithm(RLUR)算法解决以上挑战并直接优化留存。通过离线和在线验证,RLUR 算法相比 State of Art 基线能够显著地提升次留指标。RLUR 算法已经在快手 App 全量,并且能够持续地拿到显著的次留和 DAU 收益,是业内首次通过 RL 技术在真实生产环境提升用户留存。该工作已被 WWW 2023 Industry Track 接收。

作者:蔡庆芃,刘殊畅,王学良,左天佑,谢文涛,杨斌,郑东,江鹏

论文地址:https://arxiv.org/pdf/2302.01724.pdf

问题建模

如图 1(a)所示,该工作把留存优化问题建模成一个无穷视野请求粒度马尔科夫决策过程(infinite horizon request-based Markov Decision Process),其中推荐系统是 agent,用户是环境。用户每次打开 App,开启一个新的 session i。如图 1(b),用户每次请求推荐系统根据用户状态决策一个参数向量,同时 n 个预估不同短期指标(观看时长、点赞、关注等)的排序模型对每个候选视频 j 进行打分。然后排序函数输入 action 以及每个视频的打分向量,得到每个视频的最终打分,并选出得分最高的 6 个视频展示给用户,用户返回 immediate feedback。 当用户离开 App 时本 session 结束,用户下一次打开 App session i+1 开启,上一个 session 结尾和下一个 session 开始的时间间隔被称为回访时间(Returning time),。  该研究的目标是训练策略最小化多个 session 的回访时间之和。

RLUR 算法

该工作首先讨论怎么预估累计回访时间,然后提出方法解决留存信号的几个关键挑战。这些方法汇总成 Reinforcement Learning for User Retention algorithm,简写为 RLUR。

回访时间预估

如图 1(d)所示,由于动作是连续的,该工作采取 DDPG 算法的 temporal difference(TD)学习方式预估回访时间。

由于每个 session 最后一次请求才有回访时间 reward,中间 reward 为 0,作者设置折扣因子在每个 session 最后一次请求取值为,其他请求为 1。这样的设定能够避免回访时间指数衰减。并且从理论上可以证明当 loss(1)为 0 时,Q 实际上预估多个 session 的累计回访时间,。 

解决延迟奖励问题

由于回访时间只发生在每个 session 结束,这会带来学习效率低的问题。因而作者运用启发式奖励来增强策略学习。由于短期反馈和留存是正相关关系,因而作者把短期反馈作为第一种启发式奖励。并且作者采用 Random Network Distillation(RND)网络来计算每个样本的内在奖励作为第二种启发式奖励。具体而言 RND 网络采用 2 个相同的网络结构,一个网络随机初始化 fixed,另外一个网络拟合这个固定网络,拟合 loss 作为内在奖励。如图 1(e)所示,为了减少启发式奖励对留存奖励的干扰,该工作学习一个单独的 Critic 网络,用来估计短期反馈和内在奖励之和。即 

解决不确定性问题

由于回访时间受到很多推荐之外的因素影响,不确定度高,这会影响学习效果。该工作提出一个正则化方法来减少方差:首先预估一个分类模型来预估回访时间概率,即预估回访时间是否短于 ;然后用马尔可夫不等式得到回访时间下界,; 最后用真实回访时间 / 预估回访时间下界作为正则化的回访 reward。

解决偏差问题

由于不同活跃度群体的行为习惯差异大,高活用户留存率高并且训练样本数量也显著多于低活用户,这会导致模型学习被高活用户主导。为解决这个问题,该工作对高活和低活不同群体学习 2 个独立策略,采用不同的数据流进行训练,Actor 最小化回访时间同时最大化辅助奖励。如图 1(c),以高活群体为例,Actor loss 为:

解决不稳定性问题

由于回访时间信号延迟,一般在几个小时到数天内返回,这会导致 RL 在线训练不稳定。而直接使用现有的 behavior cloning 的方式要么极大限制学习速度要么不能保证稳定学习。因而该工作提出一个新的软正则化方法,即在 actor loss 乘上一个软正则化系数:

这个正则化方法本质上是一种制动效应:如果当前学习策略和样本策略偏差很大,这个 loss 会变小,学习会趋于稳定;如果学习速度趋于稳定,这个 loss 重新变大,学习速度加快。当,代表着对学习过程不加任何约束。

离线实验

该工作把 RLUR 和 State of the Art 的强化学习算法 TD3,以及黑盒优化方法 Cross Entropy Method (CEM) 在公开数据集 KuaiRand 进行对比。该工作首先基于 KuaiRand 数据集搭建一个留存模拟器:包含用户立即反馈,用户离开 Session 以及用户回访 App 三个模块,然后在这个留存模拟器评测方法。

表 1 说明 RLUR 在回访时间和次留指标显著优于 CEM 和 TD3。该研究进行消融实验,对比 RLUR 和只保留留存学习部分 (RLUR (naive)),可以说明该研究针对留存挑战解决方法的有效性。并且通过对比,说明最小化多个 session 的回访时间的算法效果优于只最小化单个 session 的回访时间。

在线实验

该工作在快手短视频推荐系统进行 A/B 测试对比 RLUR 和 CEM 方法。图 2 分别显示 RLUR 对比 CEM 的 App 打开频次、DAU、次留、7 留的提升百分比。可以发现 App 打开频次在 0-100 天逐渐提升乃至收敛。并且也拉动次留、7 留以及 DAU 指标的提升(0.1% 的 DAU 以及 0.01% 的次留提升视为统计显著)。

总结与未来工作

本文研究如何通过 RL 技术提升推荐系统用户留存,该工作将留存优化建模成一个无穷视野请求粒度的马尔可夫决策过程,该工作提出 RLUR 算法直接优化留存并有效地应对留存信号的几个关键挑战。RLUR 算法已在快手 App 全量,能够拿到显著的次留和 DAU 收益。关于未来工作,如何采用离线强化学习、Decision Transformer 等方法更有效地提升用户留存是一个很有前景的方向。

有关快手:通过强化学习提升用户留存的更多相关文章

  1. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  2. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  3. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  4. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  5. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  6. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  7. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  8. 通过 MacPorts 的 RubyGems 是个好主意吗? - 2

    从MB升级到新的MBP后,Apple的迁移助手没有移动我的gem。我这次是通过macports安装ruby​​gems,希望在下次升级时避免这种情况。有什么我应该注意的陷阱吗? 最佳答案 如果你想把你的gems安装在你的主目录中(在传输过程中应该复制过来,作为一个附带的好处,会让你以你自己的身份运行geminstall,而不是root),将gemhome:键设置为您在~/.gemrc中的主目录中的路径. 关于通过MacPorts的RubyGems是个好主意吗?,我们在StackOverf

  9. ruby - 通过 RVM 安装 Ruby 1.9.2 永远行不通! - 2

    当我执行>rvminstall1.9.2时一切顺利。然后我做>rvmuse1.9.2也很顺利。但是当涉及到ruby​​-v时..sam@sjones:~$rvminstall1.9.2/home/sam/.rvm/rubies/ruby-1.9.2-p136,thismaytakeawhiledependingonyourcpu(s)...ruby-1.9.2-p136-#fetchingruby-1.9.2-p136-#downloadingruby-1.9.2-p136,thismaytakeawhiledependingonyourconnection...%Total%Rece

  10. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

随机推荐