转载

用Golang写一个搜索引擎(0xFF)

今天这一篇的序号是0xFF,算是外篇吧,和Golang没什么关系,和代码也没什么关系,今天说说搜索引擎的排序吧。

一个标准的搜索引擎有三个最重要的部分, 爬虫,检索,排序

  • 爬虫水太深了,各种黑科技层出不穷,光代理的选择就有各种黑科技,而且只有百度这种全网搜索引擎或者某些靠爬数据的细分领域的垂直搜索引擎才需要爬虫,重要的是我也不是很了解这一块,所以就说不了了,我么默认数据都是自有的数据,类似电商的搜索引擎。

  • 检索的话,我之前的文章主要介绍的就是这一块的东西。

  • 排序是直接影响用户体验的部分,这也是搜索引擎和数据库效果上差别比较大的部分了,排序完全可以写一本书出来,这里我就用一篇文章来说说我所理解和了解的排序吧。

我没见过大厂的搜索,所以可能说得不对啊

首先,我们还是定个标准,因为搜索引擎的排序根据场景的不同使用的技术也不太一样,比如通用搜索引擎,像谷歌和百度这种, PageRank 是主要技术了,对于一个不需要爬虫的搜索引擎,一般也不会用到PageRank技术了,我们说说特定领域的搜索引擎的排序,最经典的场景就是电商类搜索引擎怎么排序。我并不是这方面的专家,所以有些东西说的不够准确也别喷啊,而且排序也是各种新技术层出不穷,一篇文章要说明白也是不太可能的,更深入的大家可以自己去找资料哈,下面我们以一个电商的搜索引擎为例说说排序。

对于搜索一个关键词,直观的感觉应该有哪些因素影响到它的结果集排序呢?一般人很明显能想到的有 关键词和商品的匹配程度,商品销量,商品好评度,是否有货等 ,再深入一点可能能想到 商品被收藏的次数,被点击的次数 这一类的东西。

OK,我们一步一步来说说吧,顺着说的时候我们先建立一个规则,就是无论多少个因素,最终每个商品都会得到一个分数,排序的时候就按这个分数来进行排序,我们这里以最简单的办法,这是一个32位的整数,我们使用其中的21位,最后就按这个21位的整数的大小来进行排序。

关键词和商品的匹配程度

首先,我们认为最重要的因素就是关键词和商品的匹配程度,也就是前面几篇所说的 TF*IDF 的值,这个我们认为是排序最重要的因素,因为你都和关键词不太匹配,怎么说也不好意思排到前面吧。那么我们把最高的3位留给 TF*IDF ,3位能表示0到7共8个等级,那么计算的时候,我们把结果集每个文档的TF*IDF算出来以后,归一化成0到7这八个数,那么对相关性的打分就打好了,如果你希望区分度更高,可以使用4位或者5位,但是其实意义不大,8个等级都多了,5个等级差不多就行了,因为后面还有其他因素,这里区分度太大了,后面就没什么影响了。

这一步的计算量比较大,可以在构建索引的时候就把每个文档在每个关键词下的TF-IDF算好直接存起来,检索的时候只需要求交集的时候把这些值加起来然后归一化就行了。

TF-IDF怎么算,可以看我前面的这篇文章【用Golang写一个搜索引擎(0x05)】,这里就不说了。

关键词匹配程度除了TF-IDF以为还有个比较重要的因素,就是词距和词序,这个也很好理解,比如你搜索 小米手机 ,结果集中有两个商品,一个名字叫 小米手机Note2,全国包邮 ,一个名字叫 优质小米,可手机追溯来源 ,有可能这两个商品的TF-IDF都是一样的值,但是很明显你更愿意看到第一个排在前面,这就是词距和词序的影响,那么,我们把接下来的2位给词距和词序,也是归一化成4个等级,怎么归一这个比较自由,能区分就行。

OK,匹配程度上有5位了,通过这5位我们基本能给出一个初步的排序结果出来了,这个结果不会太差,至少基本上会是你要找的东西,而我实现的这个搜索引擎基本也就做到这一步了,因为后面的排序因素和场景就太相关了,但是这32位我都留着了,后面的可以自由发挥。

当然,影响相关性的可不止这两个因素,像分词程序的好坏,关键词纠错能力都直接影响这一部分的排序结果,这里我们就说主要的,给大家一个排序的概念。

商品本身的属性

除了上面的匹配程度以为,商品本身的属性也是很重要的排序因素,这些属性包括 销量,收藏次数,点击次数,评论次数,好评次数,差评次数,是否有货等等等等 ,你能想到的和商品本身有关的东西(也叫feature)都可以算进来,甚至可以包括像有几张图片啊,图片是否漂亮啊,评论中是否有人晒图啊,对于某个属性,比如销量,还可以细分成日销量,周销量,月销量,这些都可以算成商品本身的属性用来影响排序。

那么我们把接下来的8位留给商品的属性吧,现在的关键问题是怎么来算这个数,最简单的办法是我们只考虑月销量,收藏次数,点击次数,并且我们人为的给拍一个 权重 就是 月销量 > 收藏 > 点击 ,他们分别占用8位中的3位,3位,2位,归一化一下,齐活,排好了,够简单吧,而且效果也不会太差。

但是作为一个高端的排序,这么做明显比较挫了,因为这一部分的打分比较稳定,它只和商品本身相关,也不需要实时计算,所以一般都是离线算好了就行了,所以这里都是用了机器学习模型或者更高端的用了深度学习模型来计算。

机器学习算什么呢?算权重,我们这里有一堆的属性(专业点叫feature)X1,X2,X3...Xn,每个都有权重分别是a1,a2,a3...aN,那么最后的分数就是a1*X1+a2*X2+a3*X3+...aN*Xn,这个分数最高的就排前面。机器学习就是把这些个a1,a2..aN系数给算出来,然后在计算每个商品的分数。

这里的方法有非常多,一般用得比较多的是逻辑回归,如果感兴趣的话可以自行去学习一下逻辑回归,不过没有数学基础就算了,我这里就不展开了,展开了就是一堆数学公式。

我用最最朴实的话描述一下这个算法啊,希望你能有个直观概念,因为我实在没法更直观的描述了,想要了解个中原理的自己去看逻辑回归吧,下面的文字有一定误导性,请谨慎阅读。

简单起见,设某个商品我们有两个属性(销量,收藏),并且我们知道这个商品最后有没有被点击,然后我们不知道他们的权重(a1,a2)需要求出来,然后用 a1*销量+a2*收藏 来得到这个商品的最后打分。

首先,我们定义一个表达式 (a1*销量+a2*收藏)*S=Y ,Y是什么呢,我们定Y=1表示被点击了,Y=0表示没有被点击,S是什么呢?你把S当成一个牛逼的函数就行了,什么东西乘上他以后就变成不是0就是1了, 现在我们把销量,收藏,是否被点击联系起来了 ,可以开始求这个a1和a2了。

我们有的是最近三个月每个商品的销量,收藏和点击数据,那么每个商品我们都可以写成下面的样子,其中的20,10,30表示销量和收藏的具体数

商品1在某时刻 : (a1*20+a2*10)*S=1

商品2在某时刻: (a1*30+a2*30)*S=0

…...

有了这一堆表达式,那么我们就一个一个去试这些系数呗,计算机不是最喜欢干这事情么,一直试到某一组系数能满足大部分表达式了,那么OK,就是它了,于是我们得到了一组能满足大部分表达式的系数,就用这组系数配合属性来计算分数了。这就是逻辑回归的机器学习算法了,注意啊,这里不是解方程,是试

于是我们把S丢掉,就用 a1*X1+a2*X2+a3*X3+...aN*Xn 给每个商品算上一个分数,再归一化一下,就是这一部分的分数了,然后填写到这8位上。

一般在这一部分,由于计算量巨大,都是用的Hadoop来算了,算出来的这一组系数一般也比较稳定,能用很久,不用每天更新,只有当数据积累到一定程度以后,再重新算一次系数就行了。这样,我们有了这组牛逼的系数,那么每天我们把所有商品的分数重新算一遍,然后更新到这8位中就行了。

然后更牛逼的是,当你发现一个新的属性(比如某个商品是不是在搞活动),你觉得应该会影响排序效果,那简单,把这个属性放进去,重新计算一下系数,以后就按新系数来计算分数了。好,黑模式开启,其实吧,算法工程师每天做的就是不停的找属性(他们管这个叫featrue,就是为了显得你们看不懂),然后让机器去算新系数,没啥难度嘛,嘿嘿。

这一切看起来都很美好,但是如何来评估也是问题。

  • 首先,这个Y怎么定,上面我们把是否点击定成Y,是不是合理,如果不合理应该怎么定,如果你有大批闲散人员,那么可以人来给每个商品打个标签【好,或者不好】来代替是否点击了,但是即便这样也有主观因素,所以这一块也是个可以深挖的东西。

  • 第二,机器这么算出来的就是对的么?我前面拍的 月销量 > 收藏 > 点击 难道就不好么?

  • 第三,除了逻辑回归,还有其他的机器学习的模型,用其他模型算出来的肯定和这个系数不一样,那哪个好呢?

所以说,算法工程师还是很忙的,还需要解决至少上面几个问题,还有一些问题,比如你找到一个属性,就是图片漂亮不漂亮应该也会影响排序,卧槽,那图片多漂亮,怎么变成一个X放到那个表达式中去啊,这也是算法工程师要解决的。

系数好不好,最简单直观的办法就是用了这一组系数以后,搜索引擎的点击提高了没,如果是电商的话,那么搜索引擎带来的收入提高了没,提高了那就行,降低了的话,对不起,把系数回滚吧。

好了,说了这么多了,其实也只是说了排序的皮毛,里面的东西实在是太多太多了,不然也不会有那么多算法工程师前仆后继的来弄这个了。

这一段写得比较多,我用了尽量能理解的话来说,如果对机器学习感兴趣的话自己去找资料吧,最好先看看线性代数和概率论,如果你不准备深入学习线性代数和概率论,只是想复习一下,那么推荐两本书,小日本写的《程序员的数学-线性代数》,《程序员的数学-概率论》。

用户本身的属性和行为

除了上面两个部分以为,用户本身的属性行为也可以作为搜索引擎排序的选项,比如我们把最后8位留给用户行为吧,何为用户本身的属性和行为呢?

比如天猫吧,在登录的情况下,搜索 上衣 ,男的和女的看到的结果是不一样的,男的看到的基本都是男上衣,女的反之。这就是用户属性的利用。又比如你在天猫上一年买的东西好几十万,而且都是高端货,那么你搜索某些关键词的时候,可能贵的东西会排前面,但我搜的时候就不会。这就是用户行为数据的利用。

总之,这一块的想象空间更加巨大,而且这一块和上一块究竟哪个的权重应该更高,也不好说,所以搜索引擎的排序这一块能做的工作实在是太多太多了,这部分也可以跟推荐系统和广告系统结合起来对搜索结果产生影响,来达到最大化的收益。具体怎么做需要单开一篇甚至几篇来写了,最终也会得到一个分数,然后放到最后的8位上去。

总结

搜索引擎的排序,不外乎就是上面三个大的部分,但是每一部分都可以深挖出很多很多东西,而且排序是关乎到一个搜索引擎好坏的重要指标,大家都是投入巨大人力做这个,一个人要全弄明白也不太可能,我文章中所说的21位整数作为打分的最终表达方式也只是其中的一种方法,只是为了让大家更直观的理解排序模型,所以排序的可操作程度实在是太高了,想怎么玩都行,只要最后有效果就是好的排序。

最后说说我个人的想法啊,就说电商排序这一块,某宝的排序目前已经是很流弊了,一般能想到的东西他们都做了,而且各种新技术新理论也用得很多,我觉得相对于其他电商已经是一个炫技的程度了,但真的都有效么?上面说的男的女的搜索出来的东西不一样,你搜的时候会觉得:"卧槽,好流弊啊!!",但仔细想想你搜东西的时候真的会因为你是男的搜的东西都是男装,你就会多下单吗?搜索是一个意图非常明确的操作,你明明是要买女装给老婆的,不会因为搜出来是男装你就会多买个男装。当然,阿里肯定是做了AB测试了,不然这个功能都上了一年多了,要是真没效果估计也下线了。

最后,道高一尺,魔高一丈,排序做得这么流弊,老子照样可以刷单刷排名,民间的高人根本不明白搜索排序的理论,一样可以分分钟秒了你的搜索排序,呵呵。。。

贴个微信公众号的二维码哈:)欢迎关注哈:)

用Golang写一个搜索引擎(0xFF)
原文  https://segmentfault.com/a/1190000005014357
正文到此结束
Loading...