相关搜索是检索功能的一个扩展,用来告诉用户自己输入查询词的情况。
如果输入错了,可能会纠错提示用户:“想找的是不是”; 或者又叫拼写检查
。
另外还会在显著位置提供与输入查询词相关的其他查询词,例如百度结果页下面的提示,
而对于电商网站这两个功能会合在一起,下面分别说说我对这两个任务的理解。
一、纠错功能,英文叫做spellcheck,在英文上做纠错比较直接,就是看单词的编辑距离,目标当然就是对于任意一个输入,能在大量正确而靠谱的查询词中找出编辑距离满足要求的一个或者几个。
面对这样的spellcheck任务,模型上就是要推算用户输入错误单词w的条件下,是正确单词c的概率,也就是argmaxc P(c|w)。一般有两种方案:一种,是http://norvig.com/spell-correct.html 介绍的办法,另一种是lucene-suggest里spellchecker的方法。
1. 第一种,在norvig介绍的方法中,详细的阐述了argmaxc P(c|w)的转换和求解办法。 这个概率不好直接算,但可以根据贝叶斯定理等价于argmaxc P(w|c)*P(c) / P(w),因为是比较各个c之间的大小所以P(w)可以省略,最后就变成求argmaxc P(w|c)*P(c)就行了。P(c)可以看作是c在文本集合中出现的可能性;P(w|c)意味着本来心里想成是c结果打成了w的概率。那就很好办了,P(c)可以从靠谱的语料中统计;P(w|c)可以用编辑距离来模拟关系,即编辑距离小的概率大。在实现上,对一个输入word,产生出有编辑距离1的字符串,就包括几种情况:删除一个字符、交换临近字符、把一个字符改成另一个、增加一个字符。这样产生的候选集会比较大,接近80%的纠错要求是满足了。如果在编辑距离1的基础上再产生编辑距离为2的更大的候选集,几乎就覆盖所有错别字了。原文讲得比较精细,建模思路也很清晰,建议仔细阅读,这就不细说了。
2.第二种方案就是lucene的spellchecker方法,上面方案是把编辑距离的临时产生到词典中检查,这种方案就是预先进行词典索引,当然是ngram的,对一个word任意2位或者3位字符进行索引,对用户输入的一个字符,也同理按2或3位产生字符片段,利用OR的关系去检索,命中多的word得分更高最可能是拼写错误的。当然因为是OR查询关系,所以会有很多也只“沾边”的词也被命中,所以最后除了考虑查询命中高分的,还要对命中的和输入的进行一步编辑距离阈值过滤。举个例子“word”,我们会有n2:wo/n2:or/n2:rd/n3:wor/n3:ord 这些碎片进行索引,当用户输入一个worg,会产生n2:wo/n2:or/n2:rg/n3:wor/n3:org,这些检索条件,会查到很多work, worth等等。细节上可以有一些增强,比如单词两头的字符碎片权重更大等等。
这两种求解argmax P(c|w)的办法,norvig的办法比lucene-spellcheck的办法在线上的环节多一些,效率上估计还是差一点,但提供了很巧妙的求解思路,值得细细品味。
二、相关搜索的功能,学术界研究的比较多,有各种提法,query rewrite,query substitution, query extension等等,算法也五花八门,大多为了结果好看加入了复杂的计算,和针对数据情况的考量。一般工程上需要的是通用的办法,再增加一些特殊的考虑来提高效果。过去曾经有幸看到一篇貌似不是很正规的论文,方法非常简单,思路清晰,非常适合在实际工程上应用起来。论文也不记得标题了,不过思想还记得很清楚:就是寻找query词之间的强弱联系。
一般情况下构成query之间的关联有三种主要的因素:
1. 字面意思的关联;如果一个query比另一个query 多了或者少了一个词,那么这两个词肯定是有关联的,长短语是短短语的具体化,反之是泛化,比如“笔记本 内存条 8G”就是“笔记本 内存条”的细化,反过来看“笔记本 内存条”不仅包括“8G”也包括其他容量,是更泛化的查询词。
2. 用户输入行为的关联;用户在一个会话之中连续输入的多个词之间可以认为是有关联的,即做一个人的需求反应在查询词上。比如用户查询了“键盘”他可能还有需要去买点别的,例如“鼠标”之类的,如果这样的情况出现了多次,那么“键盘”和“鼠标”就可以看成是有强联系的。
3. 用户点击行为的关联;用户为了找一个东西的时候可能词不对反复更换查询词,或者不同人用不同的表达,如果都点到一个结果,可以看做用了不同的办法找到同样的东西,殊途同归的味道。那么这些落到同一结果的路径,即query,也可以看做是有强关联的。
这三种是比较通用的关联关系,也很直接,并且数据能很容易获得或者被日志记录下来的。除了这几种,还可以根据具体业务情况增加其他关联考虑。最后,我们可以根据经验或者统计分析调整多种关联关系的权重。实现上,对一个query,需要让查那些和它有关联的queries,都能被找出来。于是想到可以用检索系统,传统的检索系统是对文档的内容直接分词出一个个token后建索引,这里是对query,进行特殊“分词”出那些关联的token去建索引。
最后,如果要把纠错和相关搜索结合在一起,就有很多综合考虑了。总之相关搜索是检索之外比较影响用户体验的一个服务,值得投入精力把它做好。