搜索算法工程师必备知识储备
首先我们知道,搜索算法关注的是搜的更准
而搜索算法流程中,我们可以分为这样几步
query理解–>召回–>相关性–>排序
因此这样几个方面是比较重要要求掌握的技术
下面一个一个的讲
query理解
这里的query理解,可以解释成,如何对用户发出的查询建模、
也是搜索最上层的工作,非常重要
用户的查询方式一般表现为文本,当然现在也有一些多模态的一些query
因此如何对query建模,如果是自然语言层面的话,可以理解成为NLU,即包括,分词,新词发现,词权重,词识别,query改写,同义词替换,意图识别,query纠错等等
例如:
-
纠错改写。针对用户输错的,没输入完全的,内容,进行修正。底层数据库只支持精准搜索,因此需要将query改写到正确的内容下。搜索引擎底层大都使用的倒排索引,只有映射到对应的倒排,才能够找到对应的资源,然而对于用户而言,某些词可能有很多说法,这些都要映射到对的词,才能够实现查询,例如同义词改写、前缀改写、拼音改写等。
-
意图识别。通过分析语义等方式,在一定的类目结构下,识别出具体意图。这个意图识别的目标,大家可以理解为告诉下游,需要在哪个库数据进行搜索。
传统方法想必很多人其实了解的并不多,但其实是搜索领域内非常常见,通过规则、词典、正则等方式进行识别,准确率高、速度快。
但是当规则和词典的泛化能力不足,召回率达不到预期。
用户在这个意图下输入的内容比较复杂,规则和词典难以覆盖:如“劳动节去哪玩”可以是一个电影意图,这里没有指向意图的实体词。
可以用NLP,通过语义分析的手段,文本分类,达到语义分析的目的,用fasttext,textcnn,bert蒸馏也可以。 -
实体识别。其实和意图识别一样,只不过,粒度更细,但是是词级别的分析,从query中抽取关键的实体,如果说意图识别是为了告诉下游该检索那个数据库,那实体识别就是为了告诉下游,在该数据库下,该检索哪些字段。
可以有词典匹配,通过词典匹配的形式进行命名实体识别
也可以用机器学习方法:最大熵、HMM、CRF都是轻量级的模型,预训练+RNN系,甚至是transformer模型则适合后续的迭代更新,但当然的随着模型变得复杂,模型体量会上升,响应时间也会上升。 -
词权重问题。query里面有两个词,两个文档分别匹配到了其中一个词,那谁能靠前?这就要看匹配到什么内容更为重要。如家宾馆,匹配到一个如家酒店和五洲宾馆,如家酒店应该在前,这里就是为了解决这个问题。
可以有统计的方法,其中tfidf最为常见,而由于query的长度都不长,所以其实就是idf的计算了。
NLP方法,其实就是序列标注问题的升级版了。
举个例子,一个query进来,首先要做什么?
- 数据预处理模块:
大小写转化。
删除标点符号(当然有的分析会保留标点,但是建议在这个场景下还是去掉更好)。
繁体转简体。
数字处理,转中文,转阿拉伯数字,甚至罗马字等吗,部分情况要删除数字。
长度截断。(总不能让用户输入一本西游记,然后你还在整吧?) - 理解模块:
分词。基操。
关键词抽取。会涉及丢词、排序等功能。
命名实体识别。一方面协助用户识别,另一方面可能会涉及数据库查询匹配的内容。在垂搜中比较常见,大搜也有但是相比之下没那么精准和常见。
紧密度分析,避免由于切词出现错误导致词义偏移的问题,这个其实并不少见,尤其是在人名上,这个是别的精准度会很低,近期的如“武大靖”,会被分为“武大 靖”,“曾舜晞”直接被分为了3个字,挺头疼的。
非法信息过滤。例如黄色、暴力血腥、反动等。 - 改写模块:
同义词改写。上面的吃鸡就要改写为和平精英,这个需要通过同义词挖掘等方式去构造词典实现。
前缀补全。非常常见,
丢词和留词。结合上述关键词提取和命名实体识别完成,有些不必要的词汇需要被删除,
近义词召回。这个召回不是从数据库中召回,而是召回近义词,具体的方法是通过embedding方法转化词汇,然后通过ball tree、simhash的方式召回与之意思相近的词汇,该模式虽然比较激进,但是能一定程度增加召回,有一定效果。
意图识别。与其说是意图,我更喜欢理解为这是直接针对底层数据结构产生的需要解决的问题,query这是一条,但是数据库有好几个,我们要去哪个数据库搜,这是需要识别的,而这个数据库的设计往往和品类、意图有关,找酒店、找景点都是不同的,所以此时就要进行意图识别,一般地方法是抽象为文本分类,但是很多时候语义本身是无法体现出真实意图的,例如少年的你,语义上其实很难分析出,有时候更复杂的会夹带一些实体识别、词性、词典之类的信息。
召回
召回一般有多路召回机制
文档搜索的话,倒排索引
Dense Retrivial的话有向量召回,一般是双塔
一般召回到集合之后,会考虑相关性过滤,因此涉及到相关性的计算
文本的话有TF-IDF,BM25
图片的话一般用embedding相似度,word2vec
用相关性过滤
排序
使用机器学习模型对召回结果做精细化的排序,Learning To Rank(LTR)。这是搜索系统中最关键的算法,几乎决定了最终的排序效果。常见的算法包括LambdaMart, RankNet, LambdaRank等,至少知道PointWise, PairWise, ListWise等几种算法的分类。深入使用过其中某几个算法。
在排序中,还涉及语义匹配和点击调权等算法,使用过DSSM, DBN等常规的算法。
- PointWise:CTR打分
- pairwise:考虑两者的相对关系了,也就是在构造机器学习模型时,输入应该是两个item的特征,最重的输出应该是两个item的大小关系
- listwise:listwise在pairwise的基础上,不仅要考虑两者之间的关系,而是尝试去考虑整个列表之间的关系,即输入端,我们放入的是所有待排序的item,而在输出端,实质上的输出是其最后的排序,而这个排序实质上是基于内部模型的一个打分系统得到的,有意思的是,这个打分系统里面,不仅会考虑单个被打分item,还会考虑所有输入item的综合信息,这样这个排序就能够体现整个列表下的特性。
DSSM系列似乎是比较流行的方法,但是提取一些特定的特征,有点的时候简单的LR、XGBOOST就能一定程度把问题解决好了
倒排索引构建、网页搜索中的爬虫、网页分析、摘要计算等,也会涉及一些算法。
-
对报表的理解能力:这部分其实更多的是把握离线优化和线上指标的一致性,以及对整个级联系统的认识。最常见的是离线的auc/hitrate涨了,为什么线上的指标没有变化;pv和click涨了,笔数没变是为啥;加一路扩召回了反而线上报表的效果呈负向。
-
对系统模块的了解程度:不同分路召回的作用,如何引入差异性,向量召回如何建模,线上如何检索,召回的merge怎么做。为啥有粗排,粗排为啥用双塔,粗排双塔和向量召回的差别,如何保持精排一致性。精排的序列有哪些,如何解决长序列的效率问题,如何实现online learning,如何进行负采样,如何校准。这中间相关性控制都在哪些地方使用。
-
在当前系统的基础上寻求增量:当auc和hitrate优化不动了,该如何寻求新的指标来指导离线优化;如何平衡扩召回和线上资源的平衡;单价上涨但是笔数不涨如何证明是稳定提升而非波动等。
总结
必备技能:
数据层面:最简单的sql,复杂的到hdfs、hive、spark
模型层面:tensorflow