全文检索技术

  基于开源软件Solr和Lucene构建高准确度和高度可配置的检索解决方案。泽元软件在Solr和Lucene的基础上,开发高效率的专业分词和新词识别系统,将Lucene的相关度算法更换成了改进型BM25F,并引入了多种人工智能模型以改进查准率和查全率。

  检索系统采用分布式架构,具有很好的扩展性、准确性和实时性,在同义词扩展、高亮查询结果、专业分词、实时索引、高效压缩、机器学习等方面,都有很强技术优势。检索系统能够根据搜索引擎所涉及的领域不同,可以快速增加自定义词典,能够达到1秒分词100万汉字的性能要求。随着数据量的不断增加,分布式架构能够很好的解决性能瓶颈,仅需简单地配置新增节点,即可快速应对数据的爆发式增长。本方案使用实时索引和高效压缩算法,不但降低了硬件资源的需求,同时提高了检索的实时性。改进的支持多域相关度融合的BM25F算法、基于机器学习的点击反馈模型、基于梯度下降的自动调参系统、Learning to Rank等先进算法模型保证了检索排序高水平的查全率和查准率。新词挖掘、自动可配的词库、高度可配的参数、自动调参等保证了系统高水平的用户体验具有很好的可持续性。

  基于梯度下降的自动调参

  我们采用基于梯度下降的自动调参方法实现对上百参数的自动调整,整个调参框架采用机器学习的方法,利用一定的标注数据和交叉验证方法来选择最优的参数。自动调参是一种监督的机器学习方法,其主要技术体现在利用近似偏导作为梯度搜索最优参数、交叉验证等。

  自动调参的前提是需要先准备一批(较少量,千量级)标注的<query, doc, label>三元组,label表示人工标注的query与doc的相关度等级,一般分为五个等级,标注的标准及示例如下表所示:

相关性(y

说明

示例

4

完美匹配。只有该条结果能够很好的匹配用户的Query

Query:参考书 中国临床肿瘤学进展2012

返回结果:该参考书的相关链接

3

非常有用。该结果对用户非常有帮助,但是可能存在不少同样非常有帮助的页面。

比如用户搜索某位作者

作者的每一部著作都可以认为是非常有用的结果,即相关性为3分

2

相关。该结果和用户搜索的Query相关,但是只能提供部分信息。

Query:薄荷

返回结果:复方薄荷脑滴鼻液(Compound Menthol Nasal Drops)

1

不相关。和查询的内容无关。

Query:甘草甜素

返回结果:复方薄荷脑滴鼻液(Compound Menthol Nasal Drops)

0

不知所云。不仅和查询的内容无关,且内容比较杂乱、空页面、死链、作弊页面等。这种情况通用搜索引擎中比较多一些,本项目中应该比较少见。

比如返回了一个作弊页面。

  调参的大体框架如下图所示,参数调整器负责整体调度,即根据当前状态判断下次需要尝试的参数组合。第一次时参数调整器将原始的人工调整的参数及查询词发送给排序模型,排序模型根据当前的参数计算相关性,然后对搜索结果排序并返回前N条结果。参数调整器记录下当前排序结果的NDCG和ERR情况。然后发送一组新的参数组合给排序模型。迭代这个过程,不断搜索新的参数组合。

J

  参数组合的调度有很多种方法,简单的是Grid Search(网格搜索),比如给定一个变化的区间和跳步,然后一个一个搜索。例如,每个参数的变化区间为[-1, 1],跳步为0.1,共需要21次尝试,即-1, -0.9, -0.8, &hellip;, 1。如果需要调整的参数为n个的话,需要搜索的次数为21n次。这种方法的好处是实现简单,在变化区间内搜索比较完全,缺点是速度太慢,当n比较大的时候,这种方法行不通。

  第二种方法则是用贪婪的方法,先在当前点附近大步搜索,比如跳步为0.5,找到一个更优的点后开始在这个更优点附近进行稍小跳步的搜索,直到很难提升为止。例如,假设当前参数为3.0,根据经验(此处依赖于训练数据的多少以及该feature的稀疏程度)设定变化区间为[-1, 1],那么该方法将会首先以0.5为步长的跳步搜索2.5,3.5,2.0, 4.0。假设当搜索到3.5时发现NDCG和ERR都明显好于现在的值3.0,则将参数当前值改为3.5,继续在3.5附近以稍小的跳步继续搜索,比如0.3,那么需要继续尝试3.2,3.8, 2.9这些点。4.1因为超出规定的变化区间,故不再尝试。

  第二种方法也有很多可改进的地方,毕竟贪婪的搜索方法容易陷入局部最优。改进的方法一般采用梯度下降的思想,即通过偏导的方式找到一条最快的路径搜索最优解。由于我们的损失函数并非连续函数,不能直接求偏导,因而采用近似的方法。实质是先看一圈,从一堆更好的点中找出一个最优的点后再更新参数的当前值,而不是贪婪法中的只要发现比现在优就会更新参数。、在上面的例子中,搜索到3.5是发现比3.0更优时,并不更新参数为3.5,而是继续搜索2.0,4.0这些点,假设最终2.0这个是最优的,那么第一轮结束后参数不是更新为3.5,而是更新为2.0。

  我们的系统采用第三种梯度搜索参数的方法,保证更快更准地找到最优参数。

  Learning to Rank

  本项目中将采用目前业界最先进的Learning to Rank模型——LambdaMART,该模型是最近两年世界排序竞赛冠军得主采用的模型,也是Bing、Yahoo等世界顶级搜索引擎采用的模型。

  LambdaMART以MART(多重加法回归树)为基本模型进行训练,利用Listwise的损失函数的构造来训练排序模型,优化过程中采用牛顿迭代法(Newton-Raphson)来确定每一个叶子节点的输出值。

  我们从系统中提取出成百上千的Feature,包括:标题长度、TF、IDF、标题命中率、标题相关度、正文相关度、基础相关度、各种加权等等。这些feature和查询词、文档以及对应的标注分数组合在一起作为LambdaMART的训练数据,LambdaMART训练得到的模型可以直接用来作为排序模型。

  分词算法

  我们的分词算法采用具有良好的切分歧义处理能力和新词识别能力的统计语言模型及词典分词算法,统计语言模型主要用于识别未登录词(下一小节新词挖掘部分将详细介绍)或者系统未配置的词汇,普通分词采用词典分词算法,即将输入的字符串中首先识别和切分出带有明显特征的确定词汇,以这些词汇为间隔点,把原输入字符串分割成较小的串再进行词典分词。为了减少单纯的匹配错误,我们的分词器采用最大匹配算法和最大切分(使每句中切出的词数最多)相结合的方式来分词。同时,分词器支持不限制个数的自定义词库,纯文本格式,一行一词,使用后台线程检测词库的更新,自动编译更新过的词库到二进制版本并加载。

  分词器工作中词典是相当重要的一个环节,其特征主要包括:

  1)多词典支持,词典功能分区。包括分词主词典(最后构建索引的索引项)、中文姓氏词典(用于识别特殊词)、停止单字词典(该词典中的字不用于构建索引项)、停止词语词典(该词典中的词不用于构建索引项)、计量单位词典(该词典中的词主要是一些计量单位)。同时可以根据需求的不同,灵活的添加相关的专业词典,以达到更好的分词效果。分词器可以将多个词典进行组合来使用。

  2)词典加载入内存使用,采用预加载和Lazy Mode模式。

  3)根据分词模式,对词典进行二次编译;

  4)词典变更侦测,即当词典文件发生变化时,可以重新加载词典。

  新词挖掘

  本项目中将使用多元语言模型实现高准确率和高召回率的新词挖掘。下面以一个简单的例子进行说明。

  假设当前系统中“甘草”和“片”都是单独的词,但是“甘草片”不是一个词语。为了证明“甘草片”是否真的是新词,我们需要利用二元语言模型进行一些统计和概率计算。我们可以计算一下,如果“甘草”和“片”真的是各自独立地在文本中随机出现,它俩正好拼到一起的概率会有多小。在整个4800万字的数据中,“甘草”一共出现了5648次,出现的概率约为0.000113。“片”字则出现了9594次,出现的概率约为0.000197。如果两者之间毫无关系,它们正好在一起的概率就应该是0.000113&times;0.000197,约为2.223乘以10的&ndash;8次方。但经过统计发现,“甘草片”在整个语料中一共出现了350次之多,出现概率约为7.183乘以10的&ndash;6次方,比原来的预测值高300多倍。根据这样的计算结果,我们有理由怀疑“甘草片”是一个新词。这里举得是二元语言模型。多元语言模型则是看更多词的组合,比如三元语言模型可能会发现“临床”“医学”“工程”组合在一起的“临床医学工程”是一个新词。

  我们还会对新词挖掘算法进行一定的自我训练。事先去除库中一部分已有词汇作为训练集,然后训练新词挖掘算法去准确地发现这些去除的“新词”,反复迭代直到算法满足需求时再真正进行新词的挖掘,同时挖掘过程依然可以进行一定的干预和迭代,使得算法准确率越来越高。

  点击模型

  我们通过提取上百的点击反馈feature(log记录系统对搜索结果和用户行为有较为详细的记录)训练一个更为精准的基于最大期望(Expectation-Maximization, EM)算法的点击模型,该模型一旦训练完成,即可直接在检索排序中应用,可以显著地提升排序质量。同时很多有用的点击反馈信息也作为feature送给前面的Learning to Rank模型。

  我们的点击模型考虑的Feature有:

  文档总的展现次数

  文档总的点击次数

  文档展现的平均位置

  文档被点击的平均位置

  文档展现最多次数的所在位置

  文档被点击最多次数的所在位置

  文档总的点击次数

  文档在所有查询词下的平均展现位置

  文档被作为第一次点击的次数

  文档作为最后一次点击的次数

  文档被作为第二次点击的次数

  文档被作为其他点击的总次数

  文档被作为唯一被点文档的次数

  第一次点击的总次数

  第二次点击的总次数

  其他点击的总次数

  只发生唯一一次点击的次数

  页面相对停留时间

  文档在第i个位置展现的次数

  文档在第i个位置被点击的次数

  此外我们还添加了该查询词下所有文档对应的上述feature,以及整个系统中所有查询词对应的上述feature。最终点击反馈的feature数量在100左右。利用这些feature和EM算法我们可以单独训练出一个高质量的点击模型。

  我们点击模型的出发点是用户的点击不仅依赖于文档的相关度,而且依赖于文档的位置:

  即用户点击的概率等于相关度 与位置偏向 的乘积,其中 , 通过EM算法不断迭代求得。

  相关推荐算法

  我们的系统采用基于用户的协同过滤模型和基于Item的协同过滤模型,使得推荐的结果能够很好的迎合用户的兴趣。

  其中基于用户的协同过滤模型的具体实现细节为:

  第一步我们根据历史数据产生一个 m*n 的用户-文档(包括要推荐的书、视频等)矩阵R,m是用户数,n是文档数,其中Rij表示第i个用户对第j个项目的相关度(我们通过用户的历史搜索、浏览、点击、购买等行为得到)。

  第二步我们设计算法寻找最近邻居:在这一阶段,主要是利用上面的用户-文档矩阵完成对目标用户最近邻居的查找。通过计算目标用户与其他用户之间的向量相似度,计算出与目标用户最为相似的“最近邻居”集合。实质是对目标用户产生一个以相似度递减排列的“邻居”集合。该过程我们分两步完成:首先采用修正的余弦相似性度量方法计算用户之问的相似度,然后根据以下方法选择我们需要的“最近邻居”:选择相似度最大的前 k个用户。

  第三步是产生推荐项目:对“邻居”们喜欢的文档进行加权排序(以目标用户与查找到的用户的相似度的值作为权值),将得分最高的一些文档作为推荐的候选集合。

  基于Item的协同过滤与此类似,但是考虑的是前面矩阵中的列向量,通过文档之间的相似度来寻找当前目标用户可能喜欢的文档。

  最终,基于用户的协同过滤模型和基于Item的协同过滤模型推荐出来的结果进行统一排序,然后选择预测评分最高的TOP-N项推荐给目标用户。