本次修炼方法请往下查看
🌈 欢迎莅临我的个人主页 👈这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合,智慧小天地!
🎇 相关内容文档获取 微信公众号
🎇 相关内容视频讲解 B站
🎓 博主简介:AI算法驯化师,混迹多个大厂搜索、推荐、广告、数据分析、数据挖掘岗位 个人申请专利40+,熟练掌握机器、深度学习等各类应用算法原理和项目实战经验。
🔧 技术专长: 在机器学习、搜索、广告、推荐、CV、NLP、多模态、数据分析等算法相关领域有丰富的项目实战经验。已累计为求职、科研、学习等需求提供近千次有偿|无偿定制化服务,助力多位小伙伴在学习、求职、工作上少走弯路、提高效率,近一年好评率100% 。
📝 博客风采: 积极分享关于机器学习、深度学习、数据分析、NLP、PyTorch、Python、Linux、工作、项目总结相关的实用内容。
🌵文章目录🌵
下滑查看解决方法
🎯 1、搜索系统介绍
在AI的发展过程中,搜索系统应该是第一个成功运用ai的业务,随着各大公司的竞争,在搜索系统的技术这块,国内主要看百度,国外看谷歌,二者由于处理的数据的形式(中文、英文)
存在较大的差异,因此,导致了二者在进行算法和策略的设计上面存在较大的差异,为了要大家更好的了解搜索系统的组成部分,我们以百度为例,介绍搜索系统的主要构成部分,具体如下所示:
1.1 query介绍
如上图所示的用户在搜索框里面搜索的词,统称为query,对于搜索系统来说,最终给用户展示什么样的结果都需要根据query为基础,因此,query的理解和解析算是搜索系统的基石,如果query解析做的不好,整体搜索系统的结果上限不高。
1.2 搜索结果
对于上图中的搜索结果,主要包括如下几个方面:视频、图文、广告、seo
,其中广告会在每个页面的下面标记为一个广告的标志,这个也是搜索系统变现的主要来源,而对于其他的搜索结果则为搜索系统通过蜘蛛系统去其他各个小网站爬取的内容,免费进行曝光。
1.3 搜索系统策略图
对于整个搜索系统来说是相对来说比较复杂的,特别想国内的百度搜索系统,里面架构图极其的复杂,甚至里面的一个小垂类的搜索系统都是相当的复杂,对整个搜索系统来说,比较复杂的其实是架构上面的问题,而对于策略算法是比较通用的,整体来说的话主要包括:query解析、召回排序
两个主要的策略模块,具体的简单策略流程如下所示:
💡 2、query解析
在搜索系统中,query解析
是整个搜索系统中最为重要的一部分,直接关系到最后搜索系统的效果好坏,其中query解析在整个搜索系统中承担的主要作用为:奠定搜索系统的展示结果、捕获用户的主要需求
。
为了更好的理解用户的需求,通过搜素系统会对用户的query通过各种策略和NLP算法来更好匹配相关的内容以满足其需求,具体主要的相关策略算法有:query切词、term权重、term紧密度、query分类、NER模型等
,下面对每个上图中query解析相关的策略算法进行详细的解释。
2.1 query切词
分词是将查询query切分成多个术语,例如:"手机淘宝"被切分为"手机 淘宝"两个术语。分词是最基础的词法分析组件,其准确性很大程度上影响着查询后续的各个处理步骤。分词和对应的词性信息可以用于后续的术语重要性分析和意图识别等多个模块。
查询的分词和粒度需要与商品侧索引构建的分词和粒度保持一致,以便进行有效的召回。目前,分词技术相对来说已经比较成熟,主要有基于词典的前向最大匹配、对所有可能的词组构造有向无环图、hmm/crf 序列标注模型以及深度学习模型+序列标注等方法。具体hmm相关算法的原理可以查看相关的文章
具体如果大家想要对query进行切词处理的话,可以通过jieba分词等工具进行实践
2.2 term紧密度
这个任务的算法就是去计算query切词后,每个term之间紧密程度,从而可以根据每个term的紧密程度来term组合从而反正切词导致过分切词的问题,具体的做法如下所示:
上述的算法将精密度计算方法,转化为一个序列化标注问题,将紧密片段识别以及对query中每个term与其前驱term的紧密度(bigram紧密度0~1)计算,抽象为label集合为{B、I、O}的序列标注任务:B代表紧密片段的起始位,I代表紧密片段的延续位,O代表非紧密片段的部分,最后预测出来每个term的紧密度程度,其实和序列化标注模型基本一致,只是label标注有差异。
- 当然也可以通过分类算法来对term进行分类计算
2.3 query意图识别
业务介绍:
对于搜索系统中的query意图识别模块,它在整个搜索系统中的作用还挺多的,主要的作用用来控制后续的内容召回,同时在排序、相关性计算等阶段也会使用到query分类的结果。
技术方案介绍:
本质是一个多标签多目标分类算法,目前常用的做法会通过bert等预训练模型对其进行训练,具体的技术框架图可以参考:
本质上如上述所示,就是一个分类模型,目前技术上相对来说也比较固定和成熟。
🔍 3、召回排序
3.1 搜索召回
搜索系统和推荐系统在召回排序阶段,比较大的一个区别就是召回模块,搜索系统更加侧重于语义之间的相关性,而推荐更加侧重用户的意图,因此,导致了二者在技术上存在较大的区别,目前搜索召回的常用策略主要为两种:一种为基于倒排索引的召回、一种基于深度学习的向量召回
倒排索引:
该方式的召回策略为,离线对所有的内容通过关键词构建为快速的kv索引库,然后在线的时候对用户搜索的query进行切词,通过单个词进行并发的请求倒排搜索,具体的框架图可以参考如下:
具体的例子如下所示:
在这里插入图片描述
向量召回:
早期大家会通过用户的query与点击的内容的title去训练一个dssm来对内容进行向量化,dssm是有监督学习,而且将query和title映射到同一语义空间中,再通过余弦相似度计算相关性,具体的模型结构如下所示:
目前大部分的公司对向量化的召回会通过bert来训练一个模型,然后对离线的数据进行向量化创建kv索引库,然后在线的时候对其进行向量化,然后进行向量的相似度计算来判断最终召回结果。
3.1 搜索排序
搜索的排序和推荐的最大区别在于搜索的粗排会进行一层相关性的打分算法,目前比较常用的相关性打分方法就是gbrank和bert打分,目前大一点的公司基本都是用的bert进行相关排序,也有很多的公司还是用的gbrank,具体的gbrank的算法策略如下所示:
3.1.1 lambdaMart排序
-
通过构建好检索表达式之后,我们通过检索表达式进行有权重的召回,最后在将召回来的结果进行拼接得到最后的召回商品,此时需要对召回来的商品进行排序从而得到相关的基础分数,具体lambdaMART排序算法的相关原理如下所示:
-
对于上述的算法流程图来说,lambdaMART算法相对于gdbt算法来说,改算法的精髓就在于前面的那个lambda值的计算,它为什么能做排序的一个很重要的原因就是改算法通过y计算得到一个lambda值,然后将每个样本的lambda值作为训练样本来训练得出排序模型,具体lambda的计算公式如下所示:
λ i , j = p i , j ∣ d e l t a N D G G ( i , j ) ∣ \lambda_{i,j}=p_{i,j}|deltaNDGG(i,j)| λi,j=pi,j∣deltaNDGG(i,j)∣
d e l t a N D G G ( i , j ) = ∣ n d c g ( 开始序列 ) − n d c g ( s w a p ( i , j ) ) ∣ deltaNDGG(i,j)=|ndcg(开始序列)-ndcg(swap(i,j))| deltaNDGG(i,j)=∣ndcg(开始序列)−ndcg(swap(i,j))∣
d c g ( i ) = ∑ i 2 l a b e l ( i ) − 1 l o g 2 ( i + 1 ) dcg(i)=\sum_i\frac{2^{label(i)-1}}{log_2(i+1)} dcg(i)=i∑log2(i+1)2label(i)−1 -
ndcg
-
全名叫归一化的折损累计增益,含义为高相关性的文档在搜索引擎结果列表越早出现越好。即高相关性的文档出现的位置越靠前,指标会越高。
c g = ∑ i = 1 p r e l i cg=\sum_{i=1}^{p}rel_i cg=i=1∑preli -
其中i表示当前文档所处位置,rel为文档的相关性
d c g = ∑ i = 1 p 2 r e l i − 1 l o g 2 ( i + 1 ) dcg=\sum_{i=1}^{p}\frac{2^{rel_i-1}}{log_2(i+1)} dcg=i=1∑plog2(i+1)2reli−1 -
这个公式的含义就是如果相关性较低的排在前面,需要对其进行惩罚,惩罚比例和所在的位置的对数值相关
n d g c = d c g i d c g ndgc=\frac{dcg}{idcg} ndgc=idcgdcg
在训练gbrank模型时,常用的文本特征具体如下所示:
0 query_seg_len query的切词数
1 is_hot_query 是否是热门query
2 query_knowledge_r query为强toB需求概率
3 item_ctr query与title匹配长度占总term的比例
4 item_cqr query与title匹配长度占总query的比例
5 item_rcqr 高权重term不在query中的比例
6 item_rctr 高权重term不在title中的比例
7 min_pos term匹配title的最小位置
8 max_pos term匹配title的最大位置
9 avg_pos term匹配title的平均位置
10 min_pos_rate term匹配title的最小位置在title长度中的比例
11 max_pos_rate term匹配title的最大位置在title长度中的比例
12 avg_pos_rate term匹配title的平均位置在title长度中的比例
13 name_matchquery_cnt title匹配到term的数量
14 is_hit_term_reverse title term逆序匹配到query term的逆序
15 name_len title长度
16 is_hit_brand 是否匹配品牌
17 is_hit_type 是否匹配到类型
18 is_hit_material 是否匹配到材质
19 is_hit_description 是否匹配到描述
20 is_hit_locate 是否匹配到地域
21 hit_cat_score 三级类目命中得分
22 hit_last_term query高权重词是否匹配到title的结尾词
23 name_score_level_bm25 bm25值
24 name_oral_vsrank_w_ctr ctr值
25 name_oral_vsrank_ctr ctr值
26 name_oral_levenshtein_distance 编辑距离
27 name_oral_weighted_levenshtein_distance 编辑距离
28 name_score_level_vsrank_ctr ctr值
29 name_oral_bm25 bm25值
30 name_oral_offset_value offset值
31 name_score_level_weighted_levenshtein_distance 编辑距离
32 name_score_level_vsrank_w_ctr ctr值
33 name_score_level_offset_value offset值
34 name_redrate_level 命中飘红词
35 name_no_red_count 未命中飘红词计数
36 name_name_attr_hit query和title是否匹配
37 name_reverse_pair_value 逆序对值
38 name_oral_vsrank_major_term_match 关键词匹配
39 name_oral_vsrank_cqr_len cqr值
40 name_oral_boost_term_hit_count 匹配boost term计数
41 name_oral_vsrank_judge_relevance 同义词召回商品的置信度
42 name_score_level_boost_term_hit_count 匹配boost term计数
43 ctr ms-index计算的ctr
44 cqr ms-index计算的cqr
45 cat_top_idx query识别一级类目idx
46 item_cat_top_idx 物料一级类目idx
47 hit_top_cat 一级类目匹配分数
48 hit_sub_cat 二级类目匹配分数
49 hit_last_cat 三级类目匹配分数
50 hit_no_top_cat 一级类目不匹配分数
51 hit_no_sub_cat 二级类目不匹配分数
52 hit_no_last_cat 三级类目不匹配分数
53 max_cat_val 三级类目模型预测最大概率值
54 use_cat_model 用的是1
3.1.2 bert排序
为了更好的理解机器学习搭建特征没法搭建完善特征的缺点,目前很多公司通过bert预训练模型来提取文本的向量化特征,从而更好的理解文本之间的相关性,通常相关性模型的训练基于搜索用户行为标注的弱监督数据,我们结合业务经验对数据做了去噪和数据映射。为了更好地评价相关性模型的离线效果,我们构建了一套人工标注的Benchmark数据集,指导模型迭代方向。具体常用的模型结构如下所示:
3.1.2 用户排序
目前在精排的时候大部分都使用的是多目标排序策略和算法,具体的相关内容介绍如下。
多目标排序整体介绍
具体目前多目标的相关工作如下所示:
为什么多目标: 在搜广推排序业务中,最终的排序目标都不是单一的,比如电商场景下:搜索和推荐既需要提升用户的ctr、cvr还需要提升GMV,广告需要提升点击率同时需要提升收入等。
在没有出现多目标之前,很多的公司的做法就是各个模型都分开训练,然后根据业务自动制定很多的规则,对各个指标的模型结果进行加权融合,从而得到最终的排序结果。
这种做法就是会出现很对的badcase,因为规则最后得出来的排序结果不是全局最优的结果,都是人工判定的,而且各个指标的权重也是很难去评估的,所以这种做法很难使得排序结果符合用户的偏好,换个角度来说就是需要用户去符合规则排序,结果肯定不是很理想。
多目标算法: 对于多个不同的目标可以训练多个不同的模型对其进行预测学习,然后在进行加权,类似kagggle上面很火的stacking的思想,但是这种做法在实际的工作中很难应用,时效性和成本太高了。
根据各个目标的重要性是否相等,可以将其分为两个大类,如果相等在看相关的目标是否具有相关性,在选择不同的算法进行任务学习。如果不相等目前的做法基本都是在目标函数上进行相关的研究。
针对任务相等的话比较有名的就是阿里的ESSM算法,如果不相等则采用MMOE系列算法进行任务处理
多目标loss对于一个算法来讲,算法结构是骨架,loss算是灵魂了,一些大神级的算法工程师都是对loss有独特的设计能力。那才是真正的大神
对于目标相关的多目标任务,就只需要将多个目标的loss进行相加训练即可,对于不相关的多目标任务,需要对目标函数进行转换,或者在优化迭代的过程中进行相关的骚操作了
ESSM算法介绍
总的来说该算法算是工业界公开并且验证了训练多目标排序算法较早的公开算法,总体上算法思想比较简单,但是可以很好的解决多目标且目标相似场景下的排序问题。
算法框架
该算法类似多塔框架,底层输入为曝光点击的数据集(x,y), 同时由于转化是在点击的数据覆盖范围类,因此,数据集(x,y)也包含了曝光转化的数据集(x,z), 然后两个任务共用一套特征交叉过程,这样可以可以加快模型的速度,最后分为两个部分,一部分去训练CTR,一部分去训练CVR,算法的框架如下所示:
上述框架中,两个任务在concatenate之前,所有的过程都是一样的;
对于上述的算法,也是需要训练的两个目标的相关性比较强时才可以得到比较好的loss,如果相关性比较低则不适合该算法框架;
由于在进行样本训练过程中,存在如下公式表达,因此,在计算p(cvr)时可以通过如下公式进行转换从而得到训练的损失loss:
essm的损失为累加loss,具体表达式如下所示:
l
(
θ
c
v
r
,
θ
c
t
r
)
=
∑
i
=
1
n
l
(
y
i
,
f
(
x
i
;
θ
c
t
r
)
)
+
∑
i
=
1
n
l
(
y
i
a
n
d
z
i
,
f
(
x
i
;
θ
c
t
r
)
∗
f
(
x
i
;
θ
c
v
r
)
)
l(\theta_{cvr}, \theta_{ctr})=\sum_{i=1}^{n}l(y_i, f(x_i;\theta_{ctr})) + \sum_{i=1}^{n}l(y_i and z_i,f(x_i;\theta_{ctr})*f(x_i;\theta_{cvr}))
l(θcvr,θctr)=i=1∑nl(yi,f(xi;θctr))+i=1∑nl(yiandzi,f(xi;θctr)∗f(xi;θcvr))
其中x为样本,y为点击数据,z为点击转换数据。
解决的问题
该算法是阿里团队针对电商场景下的CVR(转换率预估) 存在的一些问题而提出的,具体算法针对的问题如下:
1、样本选择偏差,训练的CVR的时候是点转数据集,但线上推理的时候是曝转数据;
2、数据稀疏问题,转化数据比点击数据少10倍以上,如果直接用深度学习去训练拟合,会遇到模型训练是欠拟合的情况。
处理方法
对于样本选择偏差的问题的处理方法,就是在ctr训练数据的基础上,添加两个分支,分别来预测logit_CTR,logit_CVR, 而对于点击再转化p(CTCVR)=p(CTR)*p(CVR)。由于最终预测时候使用的是p(CVR),而不是p(CTCVR)。对于上述的ctr训练数据,对于CVR分支,只需要将label从点击转为转化即可,这样就是直接对曝光转化数据进行建模了,对于CVR模型来说训练数据分布和在线数据分布就比较相似了。
防止欠拟合,导致训练好的模型参数中太多初始化随机数的方法是:他训练一个CTR模型,用训练好的CTR模型结构的参数共享给CVR模型,不准确一点说,就是在训练好的CTR模型上,finetune一下来训练CVR,当然,finetune后的模型也要满足CTR的loss要求。
MMOE算法介绍
对于上述的算法,如果而且的目标不是很相关的话,如果通过上述的算法进行学习,在共享embbding层和特征提取层会给后面进行单独任务学习引入很多的噪声,从而导致模型效果欠佳,为了处理该问题,google的mmoe算法通过一个gate网络来控制每个任务的权重,使得不同目标分别学习自己的Gate,具体的算法框架如下所示:
如上图所示,a为任务共享的情况和essm有点类似,b为omme通过一个总体的门网络来控制每个专家网络的权重,c为mmoe对每个目标由各自的gate网络来控制各个专家网络的贡献程度,同时各个专家网络都是独立的。
对于c中的mmeo来说,其思想就是stacking的思路很像,具体数学的表达方式为如下所示:
y
k
=
∑
i
=
1
n
g
k
(
x
)
i
f
i
(
x
)
y_k=\sum_{i=1}^{n}g^k(x)_if_i(x)
yk=i=1∑ngk(x)ifi(x)
g
k
(
x
)
=
s
o
f
t
m
a
x
(
w
g
k
(
x
)
)
g^k(x)=softmax(w_{gk}(x))
gk(x)=softmax(wgk(x))
其中,
y
k
y_k
yk为每个专家任务的输出,
f
i
(
x
)
f_i(x)
fi(x)为每个专家网络,
g
k
(
x
)
g^k(x)
gk(x)为每个目标对应控制各个专家网络权重的门网络,就是一个softmax层数据进行输出
对于上述的专家网络都是比较浅层的dnn,可以横向堆砌也可以纵向堆砌,后续很多的研究将dnn换成lstm来学习用户的时序行为,由于目前的专家网络都是独立的,可以将添加一个共有的网络,具体如下所示:
对于上述的多目标,如果目标之间的样本空间差异较大,同时没有相关的样本欠拟合问题,可以通过参数来控制损失函数来提升训练效果,具体优化的损失函数如下所示:
l
k
(
θ
k
,
θ
s
)
=
1
∑
i
a
k
i
∑
i
a
k
i
l
o
s
s
k
(
y
k
′
(
θ
k
,
θ
s
)
,
y
k
i
)
l_k(\theta_k, \theta_s)=\frac{1}{\sum_ia_k^i}\sum_ia_k^iloss_k(y_k^{'}(\theta_k, \theta_s), y_k^i)
lk(θk,θs)=∑iaki1i∑akilossk(yk′(θk,θs),yki)
- 其中 a k i a_k^i aki取值为0或者1,表示第i个样本是否属于第k个任务的样本空间