策略算法工程师之路-排序模型(LTR)及应用
策略算法工程师之路-排序模型(LTR)及应用
目录
1.简述
2.Pointwise类
2.1 LR
2.2 MLR
2.3 GBDT + LR
2.4 FM/FFM
2.5 深度模型之DNN
2.6 深度模型之Wide&Deep
2.7 深度模型之DeepFM模型
2.8 深度模型之DCN模
2.9 深度模型之DIN模型
2.10 深度模型之DIEN模型
2.11 深度模型之语义相似模型
3.Pairwise类
3.1 RankNet排序模型
3.2 xgboost+pairwise
4.特征工程
5.应用示例-论文检索系统
1.简述
随着移动互联网的崛起,越来越多的用户开始习惯于从手机完成吃、喝、玩、乐、衣、食、住、行等各个方面的需求。打开手机,点开手淘、美团等APP,商品玲玲满目,而让用户将所有商品一页页看完已经不现实,通常情况下用户也就查看前几页,如果找不到满意的商品则退出,从而造成流单。因此如何对商品进行排序使得用户感兴趣的商品尽量排在前面从而提高交易匹配效率是平台重点攻克的方向。
同样的问题出现在通用搜索引擎中,比如Baidu、Google等,当用户输入Query(查询词)时,引擎通过对用户Query的理解将最相关的信息排在最前面,从而提高信息匹配的效率。
总而言之,在互联网产品中排序是重要研究的问题。而用机器学习方法解决排序问题的方法称为LTR(Learning to Ranking)。排序系统的工作示意图如下:
L2R可以分为三大类,Pointwise、Pairwise、Listwise,下面分别做介绍。
参考资料:
1.学习排序 Learning to Rank:从 pointwise 和 pairwise 到 listwise,经典模型与优缺点
https://blog.csdn.net/lipengcn/article/details/80373744
2.浅谈排序学习
3.Learning to rank基本算法小结
**2.**Pointwise类
将排序问题转化为分类问题或者回归问题。考虑单一文档作为训练数据,不考虑文档间的关系。以分类问题来说,即对于查询,文档集,可以形成这样的训练样例个,对于二分类问题学习目标可以分为相关()和不相关(),然后训模型,对未知的样本做相关性预测。
CTR(点击率预估)问题是Pointwise的典型应用,研究的相对比较成熟,广泛应用于广告、搜索、推荐中。CTR问题的数学表达式,其中的范围为,即的值越大表示用户点击概率越高。
本小节介绍以CTR预估模型为例介绍下Pointwise的演化过程。
2.1 LR(logistics regression)
LR(logistics regression),是CTR预估模型的最基本的模型,也是工业界最喜爱使用的方案,排序模型化的首选。LR可以处理大规模的离散化特征、易于并行化、可解释性强。同时LR有很多变种,可以支持在线实时模型训练(FTRL)。
LR的数学表达式如下:
其中,
假设,,, 则
LR假设各特征间是相互独立的,忽略了特征间的交互关系,因此需要做大量的特征工程。同时LR对非线性的拟合能力较差,限制了模型的性能上限。通常LR可以作为Baseline版本。
2.2 MLR
简言之,就是多个的加权组合。的数学表达式如下:
其中,
有更强的非线性拟合能力。
2.3 GBDT + LR
GBDT(梯度提升决策树)是一种表达能力比较强的非线性模型。GBDT的优势在于处理连续值特征,而且树的分裂算法使其具有一定的组合特征的能力。在推荐系统的绝大多数场景中,出现的都是大规模离散化特征,如果我们需要使用GBDT的话,则需要将很多特征统计成连续值特征(或者embedding),这里可能需要耗费比较多的时间。鉴于此Facebook提出了一种GBDT+LR的方案。如下图:
即先使用GBDT对一些稠密的特征进行特征选择,得到的叶子节点,再拼接离散化特征放进去LR进行训练。
此方案可以看成利用GBDT替代人工实现连续值特征的离散化,而且同时在一定程度组合了特征,可以改善人工离散化中可能出现的边界问题,也减少了人工的工作量。
GBDT本质是对历史的记忆,而GBDT+LR则强化了GBDT细粒度的记忆能力!
参考资料:
**1.**CTR预估[十一]:Algorithm-GBDT Encoder
https://zhuanlan.zhihu.com/p/31734283
2.推荐系统遇上深度学习(十)–GBDT+LR融合方案实战
3.短视频如何做到千人千面?FM+GBM排序模型深度解析
2.4 FM/FFM
LR模型假设特征之间是相互独立的,忽略了特征间的交互作用,而FM则是在这个基础上进改进。FM的模型公式为:
其中为二次交叉项,表达了特征两两之间的相互作用。而二次项权重矩阵可能会存在由于数据稀疏问题带来的不置信问题,同时当特征维度较高时存储空间复杂度较高。
一种改进的方法是,其中为对应特征的特征向量。
此时:
比如,对于天气特征, 时间特征,则两个特征的交互权重为。同时对于性别特征,与的交互权重为。
直观上,天气特征对时间特征、性别特征的作用是不一样的,使用同样的向量可能会损失部分信息。因此一种改进的方式是引入(域)的概念,即, 也就是天气特征对时间特征、性别特征的向量是不一样的。这称之为算法,公式如下:
关于交叉部分的公式推导:
2.5 深度模型之DNN模型
神经网络是基于感知机的扩展,而DNN可以理解为有很多隐藏层的神经网络。多层神经网络和深度神经网络DNN其实也基本一样,DNN也叫做多层感知机(MLP)。DNN按不同层的位置划分,神经网络层可以分为三类,输入层,隐藏层和输出层,如下图示例,一般来说第一层是输入层,最后一层是输出层,而中间的层数都是隐藏层。
层与层之间是全连接的,也就是说,第层的任意一个神经元一定与第层的任意一个神经元相连。虽然DNN看起来很复杂,但是从小的局部模型来说,它还是和感知机一样,即一个线性关系加上一个激活函数。
通常神经网络的输入层维度不宜过高,否则导致模型参数量剧增。而推荐搜索等排序应用中,商品ID、用户ID类特征的维度通常是亿级别的,为了缓解此问题一般将ID映射为固定维度的Embedding向量。
通过Embedding层,将高维离散特征转换为固定长度的连续特征,然后通过多个全联接层,最后通过一个sigmoid函数转化为0-1值,代表点击的概率。即Sparse Features -> Embedding Vector -> MLPs -> Sigmoid -> Output。这种方法的优点在于:通过神经网络可以拟合高阶的非线性关系,同时减少了人工特征的工作量。
下图是DNN用于CTR预估的网络结构,即用户偏好的商品和店铺作为特征,来预测对未知商品是否会点击。
上图所示模型首先把one-hot或multi-hot特征转换为特定长度的embedding,作为模型的输入,然后经过一个DNN的part,得到最终的预估值。特别地,针对multi-hot的特征,做了一次element-wise+的操作。这样,不管特征中有多少个非0值,经过转换之后的长度都是一样的。
从业务上讲,以上模型充分利用了用户的历史偏好对未知做出预测。
以下是百度DNN模型在CTR预估中的应用:
2.6 深度模型之Wide&Deep
Wide&Deep模型
Google发表在DLRS 2016上的《**Wide & Deep Learning for Recommender System》,提出了一种将深度学习应用于推荐系统的方法,在工业生产中得到了广泛的应用。Wide&Deep模型的核心思想是结合线性模型的记忆能力和DNN模型的泛化能力,从而提升整体模型性能。Wide&Deep已成功应用到了Google Play的app**推荐业务。
将线性模型组件和深度神经网络组件进行融合,形成了在一个模型中实现记忆(Memory)和泛化(Generalization)的宽深度学习框架。下面分别简单介绍下记忆**(Memory)**和泛化(Generalization)的含义。
1). Memory(记忆性)
wide部分长处在于学习样本中的高频部分,优点是模型的记忆性好,对于样本中出现过的高频低阶特征能够用少量参数学习。缺点是模型的泛化能力差,例如对于没有见过的ID类特征,模型学习能力较差。
2). Generalization(泛化性)
deep部分长处在于学习样本中的长尾部分,优点是泛化能力强,对于少量出现过的样本甚至没有出现过的样本都能做出预测。缺点是模型对于低阶特征的学习需要用较多参才能等同wide部分效果,而且泛化能力强某种程度上也可能导致过拟合出现badcase。
实例介绍
1). 美团在外卖搜索排序中W&D模型的网络架构
2). Google在google paly商店的推荐应用排序中W&D模型的网络架构
数学表达如下:
2.7 深度模型之DeepFM模型
DeepFM是哈工大Guo博士在华为诺亚实验室实习期间,提出的一种深度学习方法,它基于Google的经典论文Wide&Deep基础上,通过将原论文的wide部分(LR部分)替换成FM,从而改进了原模型依然需要人工特征工程的缺点,得到一个end-to-end 的深度学习模型。
也就是将2.6所讲的W&D中的线性部分替换成2.4中的就是所谓的DeepFM模型。模型的架构如下:
数学公式如下:
将W&D线性部分替换成后增强了低阶特征的表达能力(二阶交叉),克服了W&D的线性部分依然需要对低维特征做特征工程的缺点。
2.8 深度模型之DCN模
上一小节讲到为了加强低阶特征的表达能力,将W&D中的LR线性部分替换成FM。FM的本质是增加了低纬特征间的二阶交叉能力,为了挖掘更高阶的特征交叉的价值提出了**DCN (Deep &Cross Network)**模型。
DCN的网络架构如下:
比较DCN与DeepFM的网络架构,可以发现本质区别是将DeepFM的FM结构替换为Cross Network结构。下面看下什么是Cross Network? 以及Cross Network是如何实现高阶特征组合的?
Cross Network结构:
Cross Network整体看是一个递推结构:
首先,为输入的特征(第一层输入),为第层的输入,为第层的参数矩阵。结合图可以看出Cross Network通过矩阵乘法实现特征的组合。每一层的特征都由其上一层的特征进行交叉组合,并把上一层的原始特征重新加回来。这样既能做特征组合,自动生成交叉组合特征,又能保留低阶原始特征,随着cross层的增加,是可以生成任意高阶的交叉组合特征(而DeepFM模型只有2阶的交叉组合特征)的,且在此过程中没有引入更多的参数,有效控制了模型复杂度。
同时为了缓解网络性能”退化“的问题,还引入了残差的思想:
残差思想
总结一下,DCN提出了一种新的交叉网络,在每个层上明确地应用特征交叉,能够有效地捕获有限度的有效特征的相互作用,学会高度非线性的相互作用,不需要人工特征工程或遍历搜索,并具有较低的计算成本。此外Cross Network可以看成是对FM的泛化,而FM则是Cross Network在阶数为2时的特例。
2.9 深度模型之DIN模型
在2.5小节中讲到DNN模型利用了用户的历史偏好信息对未知做出预测,然而阿里的研究者们通过收集用户真实数据发现用户行为有两个重要的特性:
1). Diversity:用户在浏览电商网站的过程中显示出的兴趣是十分多样性的。
Diversity体现在年轻的母亲的历史记录中体现的兴趣十分广泛,涵盖羊毛衫、手提袋、耳环、童装、运动装等等。而爱好游泳的人同样兴趣广泛,历史记录涉及浴装、旅游手册、踏水板、马铃薯、冰激凌、坚果等等。
2). Local activation体现在,当我们给爱好游泳的人推荐goggle(护目镜)时,跟他之前是否购买过薯片、书籍、冰激凌的关系就不大了,而跟他游泳相关的历史记录如游泳帽的关系就比较密切。
显然,2.5小节中对所有物品简单做element-wise+的操作无法表达上述两种特性,因为这里将所有物品或店铺向量视作同等重要。
为了解决该问题阿里提出的DIN模型中使用了weighted-sum机制,其实就是加权的sum-pooling,权重经过一个activation unit计算得到,即**Attention(注意力)**机制。
Attention机制也是一个小的神经网络模型,针对不同的候选项,用户历史行为与该候选项的权重是不同的。假设用户有ABC三个历史行为,对于候选项D,那么ABC的权重可能是0.8、0.1、0.1;对于候选项E,那么ABC的权重可能是0.3、0.6、0.1。这里的权重,就是Attention机制即上图中的Activation Unit所需要学习的。
下图是注意力机制的简单示例:
下面是一张更详细的DIN网络结构图:
2.10 深度模型之DIEN模型
前面介绍的深度兴趣网络DIN(Deep Interest Net)提出在电商场景下,用户同时会存在多种多样的兴趣,同时用户在面对一个具体商品的时候只有部分和此商品相关的兴趣会影响用户的行为。DIN提出了一个兴趣激活的模块(注意力机制),用于根据被预测的候选项C激活其相关的历史行为从而表达用户和此商品C相关的部分兴趣。相比以往的模型需要用一个固定的向量表达用户所有的兴趣,DIN用一个根据不同被预测商品变化的向量来表达用户相关的兴趣,这样的设计降低了模型表达用户兴趣的难度。
然而DIN也有其不足:
1).用户的兴趣其实是一个更为抽象的概念,而DIN的设计中直接**将一个具体的用户行为(如点击一个具体的商品)**当做了用户的兴趣。
比如用户购买了某款连衣裙,其背后可能是因为触发了用户对颜色、品牌、风格、当季相关的隐藏兴趣,而用户的兴趣并不仅仅局限于这一款具体的商品。
某个用户一段历史行为序列是:
其中,代表兴趣空间内的两种不同兴趣。
兴趣隐藏在行为背后,用户的历史行为可以看做是多个兴趣的很多采样点混合在一起的综合序列。这样的序列与自然语言处理遇到的有序序列是完全不同的,在这样的场景下,序列被打断是一个常规行为。因此单纯的序列建模,比如RNN、LSTM、GRU模型等,在这种场景下效果是不理想的。
如下图,表示用RNN根据用户历史的行为预测未来的兴趣:
RNN兴趣预测
**2).**DIN忽略了对用户兴趣演化的构建
用户的浏览历史看上去杂乱无章,但其中也隐含着规律性,比如一个女孩看了上衣、裤子后,接下来可能要看下鞋子相关的商品,上衣->裤子->鞋子,这几个兴趣间隐含着某种关联性。
为了解决上面的问题,阿里提出的DIEN(深度兴趣进化网络)中引入了两个新的模块,分别是:兴趣提取模块和兴趣演化模块。
DIEN的网络模型如下:
用户历史行为->兴趣抽取模块->兴趣演化模块,简约一点的表示如下:
什么是兴趣抽取模块?
行为是具体的,兴趣是抽象的,直接用行为Embedding当兴趣缺乏抽象、概括能力。兴趣提取模块的目的就是挖掘出行为背后用户抽象兴趣的表达。
假设用户浏览了一条裤子,那么裤子id是一个特征,该特征对于推荐系统来说是一个较为随机的特征,然而这个id类特征背后代表的可能是用户喜欢这个裤子的颜色、样式、功能等某更抽象的兴趣。
由于用户某一时刻的兴趣,不仅与当前的行为相关,也与历史各个时刻的行为相关。因此可以用时序模型对上述问题建模,比如LSTM、GRU等。
DIEN模型采用GRU模型,因为GRU在效果相差无几的前提下,比 LSTM要节省更多的参数。在神经网络模型整体结构非常复杂的大前提下,会尽量将每一个模块简单化、轻量化。
用GRU提取出的隐层状态表达用户兴趣的抽象。同时还引入了辅助loss的功能,用来辅助提取兴趣表达,有如下好处:
1).辅助loss利用的label反馈是点击序列pattern而不仅仅是ctr信号。
2).能有效解决长序列梯度传播问题,因为在现实场景中,用户兴趣序列有可能非常长,若直接用GRU,没有辅助loss,则会面临长序列梯度消失问题。
3).通过点击pattern的学习,出来hidden state能学的更好,Embedding通过反向传播也能学到更多语义表达,使得学习更加有效。
什么是兴趣演化模块?
兴趣提取模块相当于是对用户历史行为提纯,去除噪声,得到用户兴趣表示。而兴趣演化模块则是在提取模块的基础上得到对未来兴趣的抽象表示,这里同样使用了GRU。
与通常GRU不同的是,这里引入了Attention机制。因为人的兴趣是多峰分布的,比如可能同时对衣服、书籍、电子产品感兴趣,通过Attention机制将筛选出与候选项相关的兴趣,忽略无关的兴趣。
AUGRU = GRU + Attention,使用attention score来控制update门的权重,这样既保留了原始的更新方向,又能根据与候选广告的相关程度来控制隐层状态的更新力度。
举2个极端的例子:
**1).**假如该时刻的行为与候选项相关度为1,我们希望这个行为能更新用户兴趣的隐状态即,而当行为与候选项不相关的时候我们要保留当前状态,即:。
**2).**假如某行为与候选广告不相关,那么隐状态的更新是, 0 向量并不会不更新,而是会将更新到一个新的地方去,这并不是我们期望的。
如下公式是常规GRU的公式,可以对比下与AUGRU的不同。
GRU
最后总结下,DIN和DIEN的最底层都是Embedding Layer,User profile, target AD和context feature的处理方式是一致的。不同的是,DIEN将user behavior组织成了序列数据的形式,并把简单的使用外积完成的activation unit变成了一个attention-based GRU网络。
2.11 深度模型之语义相似模型
Pointwise除了广泛应用于推荐搜索中CTR预估问题外,在问答系统、同义词扩展中也有很多应用。
1).CNN(Learning to Rank Short Text Pairs with Convolutional Deep Neural Networks)
Paper:http://eecs.csuohio.edu/~sschung/CIS660/RankShortTextCNNACM2015.pdf
Code:https://github.com/YETI-WU/Semantic_Analysis_NLP/blob/master/rank_TextPairs.py
Semantic analysis. GloVe word embedding + Conv1D + MaxPool, concatenated with similarity matching, forward to Softmax layer and following the logistic regression output, binary cross entropy loss function to identify the matching similarity of documentary and query in sklearn datasets fetch_20newsgroup training.
2).DRMM(Deep Relevance Ranking Using Enhanced Document-Query Interactions)
Paper:http://nlp.cs.aueb.gr/pubs/emnlp2018.pdf
3).DSSM
// TODO
4).预训练模型(Bert等)
参考资料:
1.DeepCTR Tensorflow
2.推荐系统中使用ctr排序的f(x)的设计-传统模型篇
https://blog.csdn.net/hellozhxy/article/details/82909472
3.深度学习在美团点评推荐平台排序中的运用
https://www.cnblogs.com/wuxiangli/p/7258474.html
4.深度学习在美团点评推荐平台排序中的运用
https://www.cnblogs.com/wuxiangli/p/7258474.html
5.短视频如何做到千人千面?FM+GBM排序模型深度解析
6.推荐系统遇上深度学习(十七)–探秘阿里之MLR算法浅析及实现
7.个性化推荐算法实战第11章排序模型总结与回顾
https://blog.csdn.net/qintian888/article/details/100871781
8.CTR预估[十一]: Algorithm-GBDT Encoder
https://zhuanlan.zhihu.com/p/31734283
9.推荐系统-重排序-CTR-FM模型及FFM等
\10. 1号店11.11:机器排序学习在电商搜索中的实战
http://www.dataguru.cn/article-10144-1.html
\11. 深度学习在CTR预估中的应用
https://blog.csdn.net/qq_16234613/article/details/81460012
12.排序学习实践—ranknet方法
https://www.cnblogs.com/LBSer/p/4439542.html
13.计算广告CTR预估系列(四)–Wide&Deep理论与实践
https://blog.csdn.net/u010352603/article/details/80590129
14.详解 Wide&Deep 推荐框架
https://zhuanlan.zhihu.com/p/57247478
15.看Google如何实现Wide & Deep模型(1)
https://zhuanlan.zhihu.com/p/47293765
16.网易如何做新闻推荐:深度学习排序系统及模型
17.DeepFM理论与其应用
18.【通俗易懂】手把手带你实现DeepFM!
19.推荐系统遇上深度学习(三)–DeepFM模型理论和实践
20.推荐系统遇上深度学习(三)–DeepFM模型理论和实践
https://github.com/wangby511/Recommendation_System
https://www.cnblogs.com/hellojamest/p/11798890.html
23.DCN(Deep & Cross Network)模型在手淘分类地图CTR预估上的应用
24.SIGIR阿里论文 | 可视化理解深度神经网络CTR预估模型
https://yq.aliyun.com/articles/709630?spm=a2c4e.11153940.0.0.67e35e397QuRTB
25.SIGIR阿里论文 | 可视化理解深度神经网络CTR预估模型
https://yq.aliyun.com/articles/709630?spm=a2c4e.11153940.0.0.67e35e397QuRTB
26.阿里妈妈DIN模型(Deep Interest Network)
27.[DIN(Deep Interest Network of CTR) Paper笔记]
28.推荐系统排序算法–DIN模型
29.【干货】近年火爆的Attention模型,它的套路这里都有!
https://mp.weixin.qq.com/s/EMCZHuvk5dOV_Rz00GkJMA
30.推荐系统排序算法–DIN模型
31.推荐系统中使用ctr排序的f(x)的设计-dnn篇之AFM模型
https://zhuanlan.zhihu.com/p/33540686
32.[DIN(Deep Interest Network of CTR) Paper笔记]
https://www.cnblogs.com/rongyux/p/8026323.html
33.Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts
34.深度学习CTR模型最全演化图谱 [王喆观点]
https://blog.csdn.net/shenziheng1/article/details/89737430
35.推荐系统遇上深度学习(二十四)–深度兴趣进化网络DIEN原理及实战!
36.深度兴趣演化网络— 阿里妈妈精准定向广告组
https://blog.csdn.net/guoyuhaoaaa/article/details/83964000
37双十一疯狂剁手,你知道阿里是如何跟踪用户兴趣演化的吗?.
38.回顾」阿里妈妈:定向广告新一代点击率预估主模型——深度兴趣演化网络
https://www.6aiq.com/article/1548857018178
39.搜狐视频个性化推荐架构设计和实践
40.机器学习实践
41.【RNN 推荐】Long and Short-Term Recommendations with Recurrent Neural Networks
42.Deep Relevance Ranking Using Enhanced Document-Query Interactions阅读笔记
https://blog.csdn.net/leo_95/article/details/101039009
43.Enhanced DRMM检索模型阅读笔记
https://zhuanlan.zhihu.com/p/46755219
44.基于 Spark 的快速短文本数据流分类方法
45.PaperWeekly 第37期 | 论文盘点:检索式问答系统的语义匹配模型(神经网络篇)
https://yq.aliyun.com/articles/174908?spm=a2c4e.11153940.0.0.62b02f72RfavVK
3.Pairwise类
Pairwise是目前比较流行的方法,相对pointwise他将重点转向文档顺序关系。它主要将排序问题归结为二元分类问题,这时候机器学习的方法就比较多了,比如Boost、SVM、神经网络等。
对于同一query的相关文档集中,对任何两个不同label的文档,都可以得到一个训练实例,如果,则赋值+1,反之为-1。于是我们就得到了二元分类器训练所需的训练样本。预测时可以得到所有文档的一个偏序关系,从而实现排序。
3.1 RankNet排序模型
RankNet是一种经典的Pairwise的排序学习方法,是典型的前向神经网络排序模型。在文档集合中的第个文档记做,它的文档特征向量记做,对于给定的一根据以上推论构造RankNet网络结构,由若干层隐藏层和全连接层构成。
如下图所示,将文档特征使用隐藏层,全连接层逐层变换,完成了底层特征空间到高层特征空间的变换。其中和结构对称,分别输入到最终的层中。文档对,,RankNet将输入的单个文档特征向量映射到,得到si=f(xi), sj=f(xj)。将Ui相关性比Uj好的概率记做Pi,j,则
RankNet
由于Pairwise中的网络结构是左右对称,可定义一半网络结构,另一半共享网络参数。模型预测的输入为单个文档的特征向量,模型会给出相关性得分。将预测得分排序即可得到最终的文档相关性排序结果。
注意这里并没有预测偏序关系,输出的是类似Pointwise的单点结果,与Pointwise类模型不同的是Pairwise的模型结构中学到了更利于区分正负样本的特征。
RankCost的损失函数为:
基于Keras的RankNet实现:
# 网络参数
def create_base_network(input_dim):
seq = Sequential()
seq.add(Dense(input_dim, input_shape=(input_dim,), activation='relu'))
seq.add(Dropout(0.1))
seq.add(Dense(64, activation='relu'))
seq.add(Dropout(0.1))
seq.add(Dense(32, activation='relu'))
seq.add(Dense(1))
return seq
# Rank Cost层
def create_meta_network(input_dim, base_network):
input_a = Input(shape=(input_dim,))
input_b = Input(shape=(input_dim,))
rel_score = base_network(input_a)
irr_score = base_network(input_b)
# subtract scores
diff = Subtract()([rel_score, irr_score])
# Pass difference through sigmoid function.
prob = Activation("sigmoid")(diff)
# Build model.
model = Model(inputs = [input_a, input_b], outputs = prob)
model.compile(optimizer = "adam", loss = "binary_crossentropy")
return model
事实上Pairwise只是一种框架,可以将图中的网络部分替换成Pointwise部分讲解的任何模型。
3.2 xgboost+pairwise
import pandas as pd
import numpy as np
from xgboost import DMatrix,train
# 训练参数
xgb_rank_params = {
'bst:max_depth':2,
'bst:eta':1, 'silent':1,
'objective':'rank:pairwise',
'nthread':4,
'eval_metric':'ndcg'
}
# 产生随机样本
#一共2组*每组3条,6条样本,特征维数是2
n_group=2
n_choice=3
dtrain=np.random.uniform(0,100,[n_group*n_choice,2])
dtarget=np.array([np.random.choice([0,1,2],3,False) for i in range(n_group)]).flatten()
#n_group用于表示从前到后每组各自有多少样本,前提是样本中各组是连续的,[3,3]表示一共6条样本中前3条是第一组,后3条是第二组
dgroup= np.array([n_choice for i in range(n_group)]).flatten()
# 构造Xgboost训练数据
xgbTrain = DMatrix(dtrain, label = dtarget)
xgbTrain.set_group(dgroup)
# 构造评测数据
dtrain_eval=np.random.uniform(0,100,[n_group*n_choice,2])
xgbTrain_eval = DMatrix(dtrain_eval, label = dtarget)
xgbTrain_eval .set_group(dgroup)
evallist = [(xgbTrain,'train'),(xgbTrain_eval, 'eval')]
# 训练模型
rankModel = train(xgb_rank_params,xgbTrain,num_boost_round=20,evals=evallist)
# 测试模型
dtest=np.random.uniform(0,100,[n_group*n_choice,2])
dtestgroup=np.array([n_choice for i in range(n_group)]).flatten()
xgbTest = DMatrix(dtest)
xgbTest.set_group(dgroup)
print(rankModel.predict( xgbTest))
输出结果:
[0] train-ndcg:1 eval-ndcg:0.98197
[1] train-ndcg:0.898354 eval-ndcg:1
[2] train-ndcg:0.898354 eval-ndcg:1
[3] train-ndcg:0.898 354 eval-ndcg:1
[4] train-ndcg:0.898354 eval-ndcg:1
[5] train-ndcg:1 eval-ndcg:1
[6] train-ndcg:0.898354 eval-ndcg:1
[7] train-ndcg:1 eval-ndcg:1
[8] train-ndcg:1 eval-ndcg:1
[9] train-ndcg:1 eval-ndcg:1
[10] train-ndcg:1 eval-ndcg:1
[11] train-ndcg:1 eval-ndcg:1
[12] train-ndcg:1 eval-ndcg:1
[13] train-ndcg:1 eval-ndcg:1
[14] train-ndcg:1 eval-ndcg:0.829501
[15] train-ndcg:1 eval-ndcg:0.829501
[16] train-ndcg:1 eval-ndcg:0.829501
[17] train-ndcg:1 eval-ndcg:0.829501
[18] train-ndcg:1 eval-ndcg:0.829501
[19] train-ndcg:1 eval-ndcg:0.829501
[ 1.3936174 1.3936174 -0.65021324 1.3936174 1.3936174 1.3936174 ]
参考资料:
**1.**LambdaFM:一种在深度学习模型架构融合pairwise的策略
2.基于Pairwise和Listwise的排序学习
https://cloud.tencent.com/developer/news/135904
3.Learning to rank的讲解,单文档方法(Pointwise),文档对方法(Pairwise),文档列表方法(Listwise)…
https://blog.csdn.net/weixin_30474613/article/details/98159675
4.RankNet
4.特征工程
5.应用示例-论文检索系统
科学研究已经成为现代社会创新的主要动力。大量科研数据的积累也让我们可以理解和预测科研发展,并能用来指导未来的研究。论文是人类最前沿知识的媒介,因此如果可以理解论文中的数据,可以极大地扩充计算机理解知识的能力和范围。
WSDM Cup 2020(国际网络搜索与数据挖掘会议) 的 DiggSci 2020赛题,供一个论文库(约含80万篇论文),同时提供对论文的描述段落,来自论文中对同类研究的介绍。参赛选手需要为描述段落匹配三篇最相关的论文。
简言之,依据用户输入Query从候选Documents中找出Top N个最相关的Documents,核心技术:文本语义理解+搜索排序。比如以下例子:
描述(输入):
An efficient implementation based on BERT [1] and graph neural network (GNN) [2] is introduced.
相关论文(输出):
[1] BERT: Pre-training of deep bidirectional transformers for language understanding.
[2] Relational inductive biases, deep learning, and graph networks.
问题解法的系统架构如下:
典型的召回->重排序架构。为了降低计算复杂度,首先从海量数据集中依据简单算法召回个较相关的文档,再利用复杂算法(Learning to)从个候选集中筛出最优的个文档作为最后的输出。
1).数据探查
数据集共给出80多万条候选论文,6万多条训练样本和3万多条本测试样本。
候选论文:paper_id(论文ID),title(标题),abstract(论文摘要),journal(论文所在期刊),keyword(论文关键词),year(论文年份)。
训练样本:description_id(描述科研的句子或段落的ID),paper_id(匹配论文的ID),description_text(对科研的描述的文本,有时为句子,有时为一段话)。
候选论文样例
训练样本样例
文本是高度非结构化的,通常需要先对其进行预处理,将其分割成的有序的单词序列,并去除掉无用的冗余信息。对于中文通常需要复杂的分词算法处理;而对于英文由于天然的空白分割相对比较简单,可以借助工具包。
由于本小节介绍的案例中数据集是英文的,这里介绍下英文文本的简单处理。对于英文通常需要经过:分词->词干化(stem)->去停用词->去特殊字符->小写化 几个处理步骤。
比如文本:
‘Pyrvinium is a drug approved by the FDA and identified as a Wnt inhibitor by inhibiting Axin degradation and stabilizing 尾-catenin, which can increase Ki67+ cardiomyocytes in the peri-infarct area and alleviate cardiac remodeling in a mouse model of MI.’
处理结果:
[‘pyrvinium’, ‘drug’, ‘approve’, ‘fda’, ‘identify’, ‘wnt’, ‘inhibitor’, ‘inhibit’, ‘axin’, ‘degradation’, ‘stabilize’, ‘尾-catenin’, ‘increase’, ‘ki67+’, ‘cardiomyocytes’, ‘peri-infarct’, ‘area’, ‘alleviate’, ‘cardiac’, ‘remodeling’, ‘mouse’, ‘model’, ‘mi’]
预处理后的数据依然不能被”计算“,需要进一步转换成可计算的结构化数据,这里指文本的向量化表示。当把文本转化到向量空间后,。常见的有One-hot、Bag of Words、TF-IDF、Embedding等。
下面再分别简单介绍下:
1).One-hot
One-hot编码又称为”**独热编码”**或”哑编码”,是一种离散表示方式。这种编码将词(或字)表示成一个向量,该向量的维度是词典(或字典)的长度(该词典是通过语料库生成的),该向量中,当前词的位置的值为1,其余的位置为0。
比如字典如下:
{‘is’: 0, ‘This’: 1, ‘CNN’: 2, ‘a’: 3, ‘anthor’: 4, ‘example’: 5, ‘LSTM’: 6, ‘TRANSFORMER’: 7, ‘NLP,’: 8, ‘NLP’: 9, ‘every’: 10, ‘good’: 11, ‘task’: 12, ‘sample’: 13, ‘module’: 14, ‘very’: 15, ‘useful’: 16, ‘That’: 17, ‘pytorch’: 18}
则”CNN LSTM TRANSFORMER“的编码结果如下:
[
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
2).BOW(Bag Of Word)
词袋模型中不考虑语序和词法的信息,每个单词都是相互独立的,将词语放入一个”袋子”里,统计每个单词出现的频率。
则”CNN LSTM LSTM TRANSFORMER “的编码结果如下:
[0, 0, 1, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
3).TF-IDF
TF-IDF全称term frequency–inverse document frequency,又称”词频-逆文本“频率。其中:
**1).TF(Term Frequency):**某个词在当前文本中出现的频率,频率高的词语或者是重要的.
**2).IDF(Inverse Document frequency):**逆文本频率。文本频率是指,含有某个词的文本在整个语料库中所占的比例。逆文本频率是文本频率的倒数。
总之是考虑了文本中每个单词的重要程度。TF-IDF的问题是不能反映词的位置信息(如标题、句首、句尾的词应该赋予更高的权重)。
4).Distributed Representation-Embedding向量
1.Word2Vec
Word2vec模型是Google团队在2013年发布的word representation方法。该方法让预训练词向量的使用在NLP领域遍地开花。
Word2vec本质是用上下文词预测中心词,或利用中心词预测上下文词。
将高维向量投影到二维平面,可以看到语义相似的单词,在空间上也比较接近。
Word2vec在生成向量的过程中考虑到词语的上下文,学习到了语义和语法的信息。同时得到的词向量维度小,节省存储和计算资源,通用性强,可以应用到各种NLP任务中。
2.ELMO
Word2vec词和向量是一对一的关系,无法解决多义词的问题。同时也无法针对特定的任务做动态优化。缓解该问题的方法是,用语言模型训练神经网络,在使用word embedding时,单词已经具备上下文信息,这个时候神经网络可以根据上下文信息对word embedding进行调整,这样经过调整之后的word embedding更能表达在这个上下文中的具体含义,这就解决了静态词向量无法表示多义词的问题。
2).粗召回阶段
使用高效的匹配算法对候选集进行粗筛,为后续精排阶段缩减候选排序的数据规模。
粗召回
常见召回策略总结:
召回策略
简单的可以综合运用BM25和TF-IDF来进行论文的召回。比如,合并选取BM25召回的前篇论文和TF-IDF召回的前篇论文,组成最终的召回论文。
实际生产环境中可以借助倒排索引(如下图)数据库支持线上实时查询,比如Elastic Search、Solr等。
倒排索引
ES是工业界广泛使用的分布式全文搜索引擎,其内核是Lucene(一种单机的索引工具)。
ElasticSearch交互流程
ElasticSearch搜索过程
在使用前首先创建索引:
def create_fields(self):
# base_url是ES服务器的地址
mapping_url = self.base_url + '/_mapping'
headers = {"Content-Type": "application/json"}
# 索引配置文件
base_data = json.dumps(read_json(DATA_DIR + 'setting.json'))
field_data = json.dumps(read_json(DATA_DIR + 'fields.json'))
# 请求创建索引
ret = requests.put(self.base_url, data=base_data, headers=headers)
if ret.status_code != 200:
raise Exception('setting es error, {}'.format(ret.text))
# 请求结果
ret = requests.put(mapping_url, data=field_data, headers=headers)
if ret.status_code != 200:
raise Exception('create index error, {}'.format(ret.text))
self.logger.info('create index success')
配置文件内容:
setting.json
{
"settings": {
"analysis": {
"filter": {
"english_stop": {
"type": "stop",
"stopwords": "_english_"
},
"english_keywords": {
"type": "keyword_marker",
"keywords": [
"example"
]
},
"english_stemmer": {
"type": "stemmer",
"language": "english"
},
"english_possessive_stemmer": {
"type": "stemmer",
"language": "possessive_english"
}
},
# 在索引前先对文本做预处理,依次经过各个filter.
"analyzer": {
"english_analyzer": {
"tokenizer": "standard",
"filter": [
# 代词词干化
"english_possessive_stemmer",
# 小写化
"lowercase",
# 去停用词
"english_stop",
# 通用词干化
"english_stemmer"
]
}
}
},
"index": {
# 召回阶段粗排序的相似度计算方法(这里是BM25算法)
"similarity" : {
"my_similarity" : { // 自定义相关度算法名称
"type" : "BM25" ,// 相关度算法
"b" : "0.75",
"k1" : "1"
}
}
},
# 索引分片数量
"number_of_shards": 10,
# 索引分片副本数(用于提高并发量和安全性)
"number_of_replicas": 2
}
}
}
#索引中包含的字段(可以类比Mysql中的表结构)
fields.json
{
"properties": {
"paper_id": {
"type": "keyword"
},
"title": {
"type": "text",
"analyzer": "english_analyzer"
},
"abstract": {
"type": "text",
"analyzer": "english_analyzer"
},
"journal": {
"type": "keyword"
},
"keywords": {
"type": "text",
"analyzer": "english_analyzer"
},
"TA": {
"type": "text",
"analyzer": "english_analyzer"
},
"TAK": {
"type": "text",
"analyzer": "english_analyzer"
}
}
}
索引单个文档:
def index_doc(self, doc):
base_url = self.base_url + '/_doc/{}'
headers = {"Content-Type": "application/json"}
# 构造文档字段
url = base_url.format(doc['paper_id'])
if doc['keywords'] == '':
doc['keywords'] = []
else:
doc['keywords'] = doc['keywords'].split(';')
doc['TA'] = doc.get('title', '') + ' ' + doc.get('abstract', '')
keyword_str = ' '.join(doc['keywords']).lower()
if keyword_str:
doc['TAK'] = doc['TA'] + ' ' + keyword_str
else:
doc['TAK'] = doc['TA']
if not doc['paper_id'].strip():
return
input_str = json.dumps(doc)
if not input_str:
return
# 请求索引文档
try:
ret = requests.put(url, input_str, headers=headers)
except:
return
批量索引文档:
def indexing_runner(self):
filename = CANDIDATE_FILENAME
pool = Pool(self.parallel_size)
start = time.time()
count = 0
failed_doc_list = []
# 并发索引文档
for item_chunk in get_chunk(read_jsonline_lazy(filename), 500):
ret = pool.map(self.index_doc, item_chunk)
failed_doc_list.extend([i for i in ret if i])
duration = time.time() - start
count += len(item_chunk)
msg = '{} completed, {}min {:.2f}s'.format(count, duration // 60, duration % 60)
self.logger.info(msg)
# 重新尝试失败的文档
for doc in failed_doc_list:
self.index_doc(doc)
以上对应如下步骤:
在索引以及数据Ready后,即可以根据用户输入的Query初步检索个最相关的文档。
同样用户输入的Query也需要经过预处理操作(分词->词干化(stem)->去停用词->去特殊字符->小写化)。同时为了避免由于用户输入错误导致索引中没有对应的词汇,进而导致的”零“召回问题,在这个阶段还可以做同义词扩展、Query纠错等处理。
def search(self, text, cites_text, top_n, paper_keywords=None):
if not text:
raise ValueError('input search text is empty')
# 抽取名词短语
noun_chunks = self.extractor.get_noun_chunk(cites_text)
noun_chunks = self.format_terms(noun_chunks)
noun_chunks = ['"' + noun + '"' for noun in noun_chunks]
# 抽取单个查询词
query_words = self.extractor.get_query_words(cites_text)
query_words = self.format_terms(query_words)
query_terms = noun_chunks + query_words
if not query_terms:
query_terms = self.extractor.get_query_words(text)
query_terms = self.format_terms(query_terms)
# 抽取重要词汇(TextRank重要度算法)
cites_keywords = self.extractor.textrank(cites_text, 15, window_size=2,
edge_weighting='binary')
# 合并所有词汇
query_terms = query_terms + cites_keywords
important_keywords = self.format_terms(self.extractor.get_query_words(text))
query_terms = query_terms + important_keywords
query_terms = [term for term in query_terms if term.strip()]
if not query_terms:
query_terms = self.format_terms([text])
# 构建ES查询字符串
query_dict = {'TA': query_terms}
es_query_obj = self.build_es_query_string_object(query_dict, top_n)
ret = requests.post(self.search_url, json=es_query_obj, headers=self.headers)
searched_paper_id = []
if ret.status_code == 200:
# 这里是按照BM25排序的前N个最相似的结果
paper_list = ret.json()['hits']['hits']
for doc in paper_list:
searched_paper_id.append(doc['_id'])
if len(searched_paper_id) < 3:
searched_paper_id = self.default_result
else:
print('search error', ret.text)
# 返回查询结果
return {'docs': searched_paper_id, 'keywords': query_terms}
上述过程只是拿到了文章的id,接下来还需要再次访问搜索引擎获取文章的详情用于构建Rerank阶段所需要的特征,如下代码。
def get_paper(paper_id):
"""
get paper content from elastic search index
:param paper_id:
:return:
"""
url = ES_API_URL + '/_doc/{}'.format(paper_id)
ret = requests.get(url)
if ret.ok:
paper = ret.json()['_source']
return paper
详细的可以参考:
https://segmentfault.com/a/1190000019630099
2.Elasticsearch权威指南
https://www.cntofu.com/book/40/stemming.html
3).重排序阶段
精排阶段基于Learning to Rank的思想进行设计,从粗召回阶段的候选集中挑选出最优的个最终结果。重排序的策略伪代码如下:
核心是的设计,也就是我们前面讲过的各种模型(Pointwise、Pairwise等)。
在模型Rerank打分前需要根据用户输入的Query(query)和召回的文档列表([doc1,doc2,doc3,doc4…])构造特征。分为Pointwise和Pairwise两种:
- Pointwise模式构造的样本形式为:<query,doc,label>(线上预测时没有label).
- Pairwise 模式构造的样本形式为:<query,doc1,doc2,label>(线上预测时没有label).
def build_batch(search_item):
qd_pairs = []
desc_id = search_item['description_id']
if desc_id in searched_ids:
return [[]]
query_text = desc_id2item[desc_id][self.args.query_field]
if self.args.rerank_model_name == 'pairwise':
docs = search_item['docs'][:topk]
for i, doc_id in enumerate(docs):
#构造<query,doc1,doc2>
for p_doc_id in docs[:i] + docs[i+1:]:
raw_item = {'description_id': desc_id,
'query': query_text, 'first_doc_id': doc_id,
'second_doc_id':p_doc_id}
qd_pairs.append(raw_item)
else:
#构造<query,doc>
for doc_id in search_item['docs'][:topk]:
raw_item = {'description_id': desc_id,
'query': query_text, 'doc_id': doc_id}
qd_pairs.append(raw_item)
关于label的确定,正样本为1,负样本为0。
训练样本
在本问题中,正样本可由上面提供的训练样本构造,而负样本的构造可以根据训练集提供的随机从论文全集中选取。
在推荐搜索排序中负样本的采样是至关重要的,可以参考以下文章:
1.推荐系统正负样本的划分和采样,如何做更合理?
https://www.zhihu.com/question/334844408
2.都说数据是上限,推荐系统ctr模型中,构造正负样本有哪些实用的trick?
https://www.zhihu.com/question/324986054
3.推荐系统之—正负样本构造trick
https://blog.csdn.net/weixin_41843918/article/details/90551343
4.关于推荐系统中召回模块建模采样方式的讨论
https://blog.csdn.net/u011233351/article/details/104951598
3.1 树模型
基于树(Xgboost、lightGBM)的方案需要特征工程的配合。在我们实践中,特征主要包括统计特征(包括F1EXP、F2EXP、TFIDF、BM25等)、Embedding类特征(包括Glove、Doc2vec等)和Ranking Features(召回阶段的排序序列特征),并且这些特征分别从标题、摘要、关键词等多个维度进行抽取,最终构建成特征集合。
一篇文档由abstract、description、title等部分组成,计算用户Query与文档每个部分的相似性度量,比如 TF-IDF、BM25、Cosin相似度、编辑距离、Embedding相似度等。
详细代码可以参考:
https://github.com/myeclipse/wsdm_cup_2020_solution/blob/master/rank/get_features.py
Pointwise的训练代码如下:
# lightGBM训练
def lgb_train(train_x,train_y,valid_x,valid_y,group_train,group_valid):
params = {
'boosting_type': 'gbdt',
'objective' : 'rank:logistic',
'metric': 'map',
'num_leaves':64,
'lambda_l1':1,
'lambda_l2':0.1,
'max_depth': -1,
'learning_rate': 0.1,
'min_child_samples':5,
'feature_fraction': 0.8,
'bagging_fraction': 0.8,
'random_state':2019,
'num_threads':30
}
lgb_train = lgb.Dataset(train_x,label=train_y,group=group_train,)
lgb_validate = lgb.Dataset(valid_x, valid_y, reference=lgb_train,group=group_valid)
model = lgb.train(params, lgb_train, valid_sets=(lgb_train,lgb_validate), num_boost_round=4000, early_stopping_rounds=100,verbose_eval=100)
return model
3.2 Bert模型
Bert原始的论文证明了,Bert预训练对几乎所有类型NLP任务(生成模型除外)都有明显促进作用。从头开始训练Bert是非常耗费资源的,通常可以基于预训练的Bert模型做Fine-tuning从而适应各类NLP任务。
Bert语义相似度模型
def get_model():
# 加载预训练模型
bert_model = load_trained_model_from_checkpoint(config_path, checkpoint_path)
for l in bert_model.layers:
l.trainable = True
# Query特征
T1 = Input(shape=(None,))
# Document特征
T2 = Input(shape=(None,))
# 模型输入
T = bert_model([T1, T2])
T = Lambda(lambda x: x[:, 0])(T)
# 模型输出(Fine-tuning)
output = Dense(n_class, activation='softmax')(T)
# 模型编译
model = Model([T1, T2], output)
model.compile(
loss='categorical_crossentropy',
optimizer=Adam(1e-5), # 用足够小的学习率
metrics=['accuracy']
)
return model
Bert模型也存在诸多问题。首先BERT模型的输入最大为512个字符,对于数据中的部分长语料需要进行截断处理,这就损失了文本中的部分语义信息;其次,本任务中语料多来自科学论文,跟已有的预训练模型还是存在偏差,这也在一定程度上限制了模型对数据的表征能力。最后,BERT模型网络结构较为复杂,在运行效率上不占优势。
参考文章
1.Query 理解和语义召回在知乎搜索中的应用
Query 理解和语义召回在知乎搜索中的应用 - AIQ - 全国最专业的人工智能大数据技术社区
2.WSDM Cup 2020检索排序评测任务第一名经验总结
https://blog.csdn.net/MeituanTech/article/details/105123252
3.An Effective Approach for Citation Intent Recognition Based on Bert and LightGBM
http://www.wsdm-conference.org/2020/wsdm_cup_reports/Task1_Ferryman.pdf
4.信息检索实验: 问答系统设计与实现
5.WSDM - DiggSci 2020
https://biendata.com/competition/wsdm2020/
6.纯干货!2020年 WSDM Cup 大赛金牌参赛方案分享与解读
7.An Adaptive Early Stopping Strategy for Query-based Passage Re-ranking
http://www.wsdm-conference.org/2020/wsdm_cup_reports/Task1_dlutycx.pdf
8.WSDM Cup 2020 引用意图识别赛道冠军解决方案(附答辩视频、PPT和代码)
https://blog.csdn.net/hecongqing/article/details/104744647/
9.WSDM Cup 2020检索排序评测任务第一名经验总结
https://cloud.tencent.com/developer/news/602383
https://github.com/myeclipse/wsdm_cup_2020_solution
https://github.com/supercoderhawk/wsdm-digg-2020
12.gensim使用指南
https://github.com/steven95421/WSDM_SimpleBaseline
14.Bert 时代的创新(应用篇):Bert 在 NLP 各领域的
Bert 时代的创新(应用篇):Bert 在 NLP 各领域的
15.WSDM___DiggSci_2020_report
16.NLP中的文本表示方法
https://zhuanlan.zhihu.com/p/42310942
17.【NLP理论】——文本在计算机中的表示方法总结
https://blog.csdn.net/dendi_hust/article/details/102772278
18.feed流个性化推荐架构和算法分享
19.searchbetter
20.query改写-拼写纠错(Spelling Correction)
https://blog.csdn.net/huanghaocs/article/details/101227139
21.【技术分享】七:搜索排序—排序模型
https://zhuanlan.zhihu.com/p/99712281
22.图像检索:再叙ANN Search
https://yongyuan.name/blog/ann-search.html?spm=a2c4e.10696291.0.0.619c19a435yCpw
https://github.com/ThomasDelteil/VisualSearch_MXNet
24.蚂蚁金服 ZSearch 在向量检索上的探索
25.从L2R开始理解一下xgboost的 ‘objective’: ‘rank:pairwise’参数
26.hnswlib
27.【技术分享】七:搜索排序—排序模型
https://zhuanlan.zhihu.com/p/99712281
https://github.com/ThomasDelteil/VisualSearch_MXNet
29.XGBoost for Ranking 使用方法
30.基于Pairwise和Listwise的排序学习
基于Pairwise和Listwise的排序学习 - 云+社区 - 腾讯云
https://github.com/ThomasDelteil/VisualSearch_MXNet
32.爱奇艺搜索排序模型迭代之路
33.网易如何做新闻推荐:深度学习排序系统及模型
34.大众点评搜索基于知识图谱的深度学习排序实践
35.DeepCTR
36.AutoIntL:使用Multi-head Self-Attention进行自动特征学习的CTR模型
https://blog.csdn.net/u012151283/article/details/85310370
37.阿里提出基于Transformer的个性化重排序模型PRM,首次用于大规模在线系统
39.[深度学习]利用DNN做推荐的实现过程总结
https://zhuanlan.zhihu.com/p/38638747
40.推荐系统中如何做 User Embedding?
https://www.zhihu.com/question/336110178
42.推荐系统之采样修正的双塔模型
https://blog.csdn.net/GFDGFHSDS/article/details/105300416
43.深度学习在花椒直播中的应用—推荐系统冷启动算法
44.深度模型DNN在个性化推荐场景中的应用
45.深度时空网络、记忆网络与特征表达学习在 CTR 预估中的应用
https://mp.weixin.qq.com/s/A_YkSoWjhvsP_vLtlk7kMg
6.其他补充
6.1 多模型融合
6.2 Attention Pooling
6.3 DNN+Embedding
6.4 Learn to Display
一般的排序模型只是给单独一个文档算分,然后按照分数大小排序。但在个性化排序中,如果两个商品比较相似,得分也会比较相似,会导致排序结果中部分结果是趋同的,多元性差。Learn to Display主要是解决这个问题,核心思路是根据已经排好序的商品预测下一个商品的分数,这里我们是用LSTM对已经排好序的商品做表征,用beam search生产排序序列。
6.5 多模态信息融合
文本+图像+…
6.6 多目标融合
推荐场景上的优化目标要综合考虑用户的点击率和下单率。在过去我们使用XGBoost进行单目标训练的时候,通过把点击的样本和下单的样本都作为正样本,并对下单的样本进行上采样或者加权,来平衡点击率和下单率。但这种样本的加权方式也会有一些缺点,例如调整下单权重或者采样率的成本较高,每次调整都需要重新训练,并且对于模型来说较难用同一套参数来表达这两种混合的样本分布。针对上述问题,可以利用DNN灵活的网络结构引入了Multi-task训练。
根据业务目标,把点击率和下单率拆分出来,形成两个独立的训练目标,分别建立各自的Loss Function,作为对模型训练的监督和指导。DNN网络的前几层作为共享层,点击任务和下单任务共享其表达,并在BP阶段根据两个任务算出的梯度共同进行参数更新。网络在最后一个全连接层进行拆分,单独学习对应Loss的参数,从而更好地专注于拟合各自Label的分布。
6.7 Transformer
6.8 Transformer(Behavior Sequence Transformer for E-commerce Recommendation in Alibaba)
6.9 Deep Spatio-Temporal Neural Networks for Click-Through Rate Prediction
输入包括目标广告信息、上下文广告信息、点击广告信息、曝光未点击广告信息,经过 embedding层,然后有两种attention方式,第一种是self-attention方式:
其实就是比如上下文的embedding表示输入到一个函数中,得到标量输出,然后通过softmax将每个上下文item的权重归一化到0-1之间,随后基于权重进行加权求和。缺点就是没有考虑的信息。
另外一种 attention 方式是交互式的,并且加入了目标广告的信息:
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!