该论文提出了一个基于DQN的推荐框架,用于解决以下3个问题:
解决方法是:
小更新只用用户点击数据对主网络和目标网络进行更新;
大更新同时用用户点击数据和用户活跃度对主网络进行更新。
论文构造了以下四个特征用于预测用户是否会点击一个特定的新闻:
这些特征将作为状态 s s s 被输入DQN进行训练,但在本论文中,Q函数被设计为V函数(价值函数)与A函数(优势函数)的组合:
如图所示,用户特征和上下文特征被输入V函数,用户特征、上下文特征、用户-新闻交互特征和新闻特征被输入A函数。
优势函数 A ( s , a ) A(s,a) A(s,a) 表示在状态 s s s 下,某动作 a a a 做出后的价值相对于平均价值 V ( s ) V(s) V(s)而言的差值: A ( s , a ) = Q ( s , a ) − V ( s ) A(s,a)=Q(s,a)-V(s) A(s,a)=Q(s,a)−V(s) Q ( s , a ) = A ( s , a ) + V ( s ) Q(s,a)=A(s,a)+V(s) Q(s,a)=A(s,a)+V(s)把 Q Q Q值分为价值函数 V V V和优势函数 A A A来训练有助于提高策略的学习效率,更容易地发现那个动作 a a a 更好。
奖励公式定义为: y s , a = Q ( s , a ) = r i m m e d i a t e + γ r f u t u r e y_{s,a}=Q(s,a)=r_{immediate}+\gamma r_{future} ys,a=Q(s,a)=rimmediate+γrfuture其中,状态 s s s 是上下文特征和用户特征 ;动作 a a a 是用户-新闻交互特征和新闻特征 ; r i m m e d i a t e r_{immediate} rimmediate 表示当前状态时的立即奖励(用户是否点击此新闻); r f u t u r e r_{future} rfuture 表示对未来奖励的预测; γ \gamma γ 是折扣因子。
以上公式在DQN中表示为: y s , a , t = r a , t + 1 + γ Q ( s a , t + 1 , arg max a ′ Q ( s a , t + 1 , a ′ ; W t ) ; W t ′ ) y_{s,a,t}=r_{a,t+1}+\gamma Q\Bigl(s_{a,t+1},\argmax_{a'}Q(s_{a,t+1},a';\mathsf{W}_t);\mathsf{W}_t'\Bigr) ys,a,t=ra,t+1+γQ(sa,t+1,a′argmaxQ(sa,t+1,a′;Wt);Wt′)其中, r a , t + 1 r_{a,t+1} ra,t+1表示采取动作 a a a 后获得的立即奖励, t + 1 t+1 t+1是因为奖励总是延迟一个时间步的; W t \mathsf{W}_t Wt和 W t ′ \mathsf{W}_t' Wt′分别的DQN的主网络和目标网络(探索网络)的参数; a ′ a' a′是DQN估计的在状态 s a , t + 1 s_{a,t+1} sa,t+1时的动作;在一定次数的迭代后, W t ′ \mathsf{W}_t' Wt′将被更新到 W t \mathsf{W}_t Wt
论文将用户与应用程序交互的频率作为用户的主动反馈信息,与用户是否点击某些推荐项一起作为用户反馈信息。
论文使用生存模型来建模用户的主动反馈。生存分析用于估计用户的返回时间,假设 t t t 是当前时间, T T T 是下一次用户返回的时间,那么衰减率可以被定义为: λ ( t ) = lim d t → 0 P r { t ⩽ T < t + d t ∣ T ⩾ t } d t \lambda(t)=\lim_{\mathsf{d}t\to 0}\frac{Pr\{t\leqslant T < t+\mathsf{d}t\quad|\quad T\geqslant t\}}{\mathsf{d}t} λ(t)=dt→0limdtPr{ t⩽T<t+dt∣T⩾t}该公式表示当返回时间与当前时间的差值 T − t T-t T−t 越大时,衰减率越大;当 T − t T-t T−t 越小时,衰减率越小,即用户返回的概率越大。为了简化问题,论文设定 λ ( t ) \lambda(t) λ(t)为一个固定的参数 λ 0 \lambda_0 λ0,也就是每个用户的衰减率被定义为恒定值。
那么, t t t 时间后用户的活跃度可以定义为: S ( 0 ) = 0.5 S(0)=0.5 S(0)=0.5 S ( t ) = e − ∫ 0 t λ ( x ) d x ⩽ 1 S(t)=e^{-\int_0^t\lambda(x)\mathsf{d}x}\leqslant 1 S(t)=e−∫0tλ(x)dx⩽1
则用户活跃度从当前点降为0所用的时间 T 0 T_0 T0 (即用户存活期)可以表示为: T 0 = ∫ 0 ∞ S ( t ) d t T_0=\int_0^\infty S(t)\mathsf{d}t T0=∫0∞S(t)dt
每当应用程序检测到用户的返回时,就将这个用户的活跃度加上一个特定值: S ( t ) = S ( t ) + S a S(t)=S(t)+S_a S(t)=S(t)+Sa。
论文将上述的几个参数分别设定为: λ 0 = 1.2 × 1 0 − 5 \lambda_0=1.2 \times 10^{−5} λ0=1.2×10−5每秒; S a = 0.32 S_a=0.32 Sa=0.32; T 0 = 24 T_0=24 T0=24小时。这样的设置可以实现当用户每天访问应用程序一次时,活跃度保持不变: S 0 e − λ 0 T 0 + S a = S 0 S_0e^{-\lambda_0T_0}+S_a=S_0 S0e−λ0T0+Sa=S0以 S 0 = 0.5 S_0=0.5 S0=0.5 为例: 0.5 e − 1.2 × 1 0 − 5 × 12 × 60 × 60 + 0.32 ≈ 0.5 0.5e^{-1.2 \times 10^{−5}\times12\times60\times60}+0.32\approx 0.5 0.5e−1.2×10−5×12×60×60+0.32≈0.5
如图所示,该特定用户的用户活跃度在时间0时从 S 0 = 0.5 S_0=0.5 S0=0.5开始衰减。在时间戳 t 1 t_1 t1 时,用户返回,此时用户活跃度 + S a +S_a +Sa。然后, t 1 t_1 t1后用户活跃度继续衰减。由于论文设定活跃度最大为1,所以该用户在 t 4 t_4 t4 到 t 9 t_9 t9 期间的用户活跃度被截断为1。
结合用户点击反馈和用户活跃度反馈,立即回报就被定义为: r i m m e d i a t e = r t o t l e = r c l i c k + β r a c t i v e r_{immediate}=r_{totle}=r_{click}+\beta r_{active} rimmediate=rtotle=rclick+βractive其中, β \beta β 是权重参数。
论文采用了DBGD(Dueling Bandit Gradient Descent)探索策略。该策略通过向主网络的参数添加噪声数据来构造新的网络参数,并把该参数作为探索网络的参数,然后利用探索网络生成推荐项,与主网络生成的推荐项合并成推荐列表,推送给用户。如下图所示:
模型更新公式表示为: Δ W = α ⋅ text ( − 1 , 1 ) ⋅ W \Delta\mathsf{W}=\alpha·\text{text}(-1,1)·\mathsf{W} ΔW=α⋅text(−1,1)⋅W W ~ = W + Δ W \widetilde{W}=\mathsf{W}+\Delta\mathsf{W} W
=W+ΔW W ′ = W + η W ~ \mathsf{W'}=\mathsf{W}+\eta\widetilde{W} W′=W+ηW
根据用户点击的推荐项属于 W \mathsf{W} W 和 W ~ \widetilde{W} W
的比例来调整 η \eta η 值,然后在进行下一次推荐之前将参数 W ′ \mathsf{W'} W′ 更新到主网络。
1. 概述作为接口服务提供方,非常有必要在项目中加入参数校验,比如字段非空,字段长度限制,邮箱格式验证等等,数据校验常用到概念:JSR303/JSR-349: JSR303是一项标准,只提供规范不提供实现,规定一些校验规范即校验注解,如@Null,@NotNull,@Pattern,位于javax.validation.constraints包下。JSR-349是其的升级版本,添加了一些新特性...
torch.nn.NLLLoss()class torch.nn.NLLLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')计算公式:loss(input, class) = -input[class]公式理解:input = [-0.1187, 0.2110, 0.7463],target = [1],那么 loss = -0.2110。个人理解:感觉像是把 target 转
发送文本消息点击发送按钮后,页面(ChatFragment.java)响应发送事件// 发送按钮点击事件ekBar.getBtnSend().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String text = ekBar.getEt
《剑指offer》刷题——【字符串】面试题5:替换空格一、题目描述:二、解题思路:三、代码实现:一、题目描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。二、解题思路:在二叉树的前序遍历中,第一个...
作 者: wfq771105 (公子小白) 等 级: 信 誉 值: 100 所属社区: 扩充话题 程序人生 问题点数: 100 回复次数: 99 发表时间: 2006-8-9 16:33:32 以前看过一篇文章说:很多人事业(工作)都有停滞期,自我满足型停滞和能力型停滞。自我满足型停滞就是事业到达了自己的要求,觉得很满足,即使还有很大的提升空间,也不愿再往前发展了...
一.DispatcherServlet的初始化在我们第一次学Servlet编程,学java web的时候,还没有那么多框架。我们开发一个简单的功能要做的事情很简单,就是继承HttpServlet,根据需要重写一下doGet,doPost方法,跳转到我们定义好的jsp页面。Servlet类编写完之后在web.xml里注册这个Servlet类。除此之外,没有其他了。我们启动web服务器,在浏览...
我们一般来说,使用for…in来遍历对象,使用for…of来遍历数组我们强烈建议不要使用for…in来遍历数组为什么???因为for…in遍历的是对象的key或者是数组的下标。当然最重要的原因是,他会到原型链上寻找,遍历其中新增加的属性的key值for of遍历的是数组元素值,for in 遍历的是数组的索引(即键名)for of遍历的只是数组内的元素,for in 遍历的不只是数组内的元素,还有其新增的原型属性和索引for of 遍历Array.prototype.method=func
创建管道共享数据[code="C++"]//创建匿名管道 SECURITY_ATTRIBUTES sa; HANDLE hRead,hWrite;sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; CreatePipe(...
Mysql Replication机制主从同步实践
1006 Sign In and Sign Out (25分)像类似于题目中时间HH:MM:SS这种特殊格式,完全可以用scanf("d%:%d:%d:".....)的格式以整型数据输入时间,而不是用字符串输入再去麻烦的转换。此外,比较时间也不必时分秒逐个比,直接统一成秒比较即可。...
关于Flutter Grpc Client 连接的管理,我写了一个,有什么不对的和可以优化的还望大家指正一下。/*** 类:ClientChannelManager * 描述:连接池管理器 * 作者:dingzuhua* 创建时间:2019/3/14 13:20*/import 'package:grpc/grpc.dart';class ClientChannelManager ...
package com.clamc.mapper;import org.junit.After;import org.junit.Assert;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.mybatis.spring.boot.test.autoc...