搜索排序之线性模型

搜索排序一般分成粗排和精排,一般来说,粗排使用线性模型,可以快速迭代出结果。后续等有用户行为之后,则进行进一步的精排模型的接入, 可以进一步提升搜索排序的精准度。今天这里主要介绍搜索排序的线性模型。

1. 背景

最近在看一本关于搜索相关的书籍《相关性搜索》, 非常适合搜索入门,特别是里面的一些思想,给我感觉有挺多感触的, 简单来讲,书上已经将相关性搜索的方方面面讲的很清楚了。感觉挺有收获的。有兴趣的同学可以看一下。

2. 规则线性模型

其中印象最深刻的是,调整相关性函数的那一章。实际上,相关性函数的设计,是一个搜索功能必须具备的一个设计能力,它也是一个搜索系统灵魂所在。只有把相关函数设计好了,才能检索出更具相关性的结果出来。

在设计相关函数,一般采用以下三种策略:

  • 加法放大: 在基准评价值的基础之上叠加放大的效果。 总价值=基础评价值+加法放大值。
  • **乘法放大:**根据放大倍数对基准评价值进行“”缩放“”。总价值=基础评价值*乘法放大值。
  • yes/no: 在yes/no的基础上,进行时效性和质量度的衰减调权。

首先来定义以下,什么是基础评价值,什么是放大值。实际上,一般来说,基础评价值,一般都是关于query和doc之间的相关性价值分,例如tf-idf/bm25等等因子,而放大值,则是一些时效性和质量度的分值。

首先来看一下加法放大:

total_score = (w1*bm25+w2*tf-idf) + (w3*quality+w4*score),

这种放大方式,比较容易出现,热度击穿的问题。

再来看一下乘法放大:

total_score = (w1*bm25+w2*tf-idf)*(w3*quality+w4*score)

这种方法方式,可以很好的解决热度击穿的问题,如果文本分较少的话,乘法相应的惩罚也会较大。所以工业界采用乘法放大的比较多。

最后看一下yes/no的方案, 实际上这种场景比较适合书上的电影场景(垂直搜索场景), 毕竟垂直搜索领域的术语比较有限,一般完全匹配可以解决80%的问题,剩下的问题,可能更多是通过时效性和质量度进行调优,特别是里面的搜索导演名的场景。

实际上,在很多时候,会把上面三种的方案,组合成一个更多元化的实现方案,可以实现对业务更好的支持。例如书上举出来的例子:

1. 精准匹配片名?————> 选择该搜索结果
2. 精准匹配人名?————> 基于时效和评分进行排名
3. 部分匹配人名?————> 稍作放大
4. 加入基准查询

实际上,使用以上这些策略,实现出来的基准也是可以已经很好满足用户的需求的。

2. 机器学习的线性模型

虽然上面的规则模型,可以很好的满足用户的需求,但是毕竟是人工规则,其中的调整参数是一个非常大的难题。具体如何调参, 可能需要相关性技术工程师,花费大量的人力物力根据top query,进行调整和尝试, 才能最终调整出一个满意的结果。

实际上,目前大部分的排序,更多的是采用机器学习的模型来实现, 权重的调整。目前业界比较流程的线性模型,主要包括LR模型和FM模型。

仔细想一想,单纯模型的预测函数来讲,上面讲的加法放大的模型,实际上就是LR模型的预测函数,而乘法放大的模型,实际上就是FM模型的二阶项的预测函数。

实际上,任何线性模型都是有迹可循的。哈哈哈。只是机器学习,使用了更加严谨的方法来实现对参数的权重进行调权和实现。不过机器学习的方法,更多的基础,是在好的数据特征和好的数据样本,不然训练出来的结果,还不如上面使用有经验的拍脑袋拍出来的权重。

第一步是,要有好的样本数据:一般是使用人工标注的数据,或者从用户的搜索日志里面提取出来对应的样本数据。对样本进行0-4的评分。

第二步是,要有好的特征,这里就考究相关性技术工程师,是否能提取出好的特征工程了,和推荐系统相比之下,推荐系统很多时候是根据用户行为进行特征提取的。当然搜索的特征工程,是一个比较核心的指标也是根据用户行为,推荐系统更多的是基于用户的特征,而搜索的项目更多是基于query的特征。

例如bm25和tf-idf则是query和doc之间的一个交叉特征。特征工程的内容这里就不展开叙述了,以后会做统一归纳。

举个简单的例子:我们根据某个query词, 搜索,然后计算对应的在线特征,包括标题分、摘要分,用户打分。如下rocky.csv(工业界的做法还需要提取大量的query和人工标注评分):

grade,titleScore,overviewScore,ratingScore,comment:# <docid> keywords@movietitle
4,10.65,8.41,7.40,# 1366   rocky@Rocky
3,0.00,6.75,7.00,# 12412  rocky@Creed
3,8.22,9.72,6.60,# 1246   rocky@Rocky Balboa
3,8.22,8.41,0.00,# 1374   rocky@Rocky IV
3,8.22,7.68,6.90,# 1367   rocky@Rocky II
3,8.22,7.15,0.00,# 1375   rocky@Rocky V
3,8.22,5.28,0.00,# 1371   rocky@Rocky III
2,0.00,0.00,7.60,# 154019 rocky@Belarmino
2,0.00,0.00,7.10,# 1368   rocky@First Blood
2,0.00,0.00,6.70,# 13258  rocky@Son of Rambow
2,0.00,0.00,0.00,# 70808  rocky@Klitschko
2,0.00,0.00,0.00,# 64807  rocky@Grudge Match
2,0.00,0.00,0.00,# 47059  rocky@Boxing Gym
  • LR模型的训练过程如下:
from sklearn.linear_model import LinearRegression
from math import sin
import numpy as np
import csv

rockyData = np.genfromtxt('rocky.csv', delimiter=',')[1:] # Remove the CSV header

rockyGrades = rockyData[:,0]   # Slice out column 0, where the grades are
rockySignals = rockyData[:,1:-1]  # Features in columns 1...all but last column (the comment)

butIRegress = LinearRegression()
butIRegress.fit(rockySignals, rockyGrades)

butIRegress.coef_  #boost for title, boost for overview, boost for rating


array([ 0.04999419,  0.22958357,  0.00573909])


butIRegress.intercept_



def relevanceScore(intercept, titleCoef, overviewCoef, ratingCoef, titleScore, overviewScore, movieRating):
    return intercept + (titleCoef * titleScore) + (overviewCoef * overviewScore) + (ratingCoef * movieRating)
    
    # Score Rambo
relevanceScore(butIRegress.intercept_, butIRegress.coef_[0], butIRegress.coef_[1], butIRegress.coef_[2],
               titleScore=12.28, overviewScore=9.82, movieRating=6.40)
# Score First Blood
relevanceScore(butIRegress.intercept_, butIRegress.coef_[0], butIRegress.coef_[1], butIRegress.coef_[2],
               titleScore=0.00, overviewScore=10.76, movieRating=7.10)

一般来说,现行模型常用的校验指标是AUC指标,而不是ltr常用的ndcg的排序模型,毕竟这里只是简单的point wise。

今天就到这里,后续补充一下fm的模型代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值