搜索引擎中相似度算法TF-IDF和BM25

前言

当我们使用搜索引擎时,它总是会把相关性高的内容显示在前面,相关性低的内容显示在后面。那么,搜索引擎是如何计算关键字和内容的相关性呢?这里介绍2种重要的相似度算法:TF-IDF和BM25

TF-IDF是Lucene上一代(6.0以前)相似度算法,BM25是Lucene新一代(6.0以后)正使用的相似度算法。

先举个例子。假如,我们想找和“Lucene”相关的文章。可以想一下,那些内容里只出现过一次“Lucene”的文章,有可能是在讲某种技术,顺便提到了Lucene这个工具。而那些出现了两三次“Lucene”的文章,很可能是专门讨论Lucene的。通过直觉,我们可以得出判断:关键字出现的次数越多,文档与关键字的匹配度越高

TF

Term Frequency,缩写为TF。通常叫做“词频”,表示文档中关键字出现的次数。

通常TF越大,相关性越高。

但是,你可能会发现一个问题。例如一篇小短文里出现了一次“Lucene”,而一部好几百页的书里提到两次“Lucene”,此时我们就不能说后者相关度更高了。为了消除文档本身大小的影响,在计算TF时引入文档长度这个参数,做文档长度标准化

TF socre = 某个词在文档中出现的次数 / 文档的长度

举例:某文档D,长度为200,其中“Lucene”出现了2次,“的”出现了20次,“原理”出现了3次,那么

TF(Lucene|D) = 2/200 = 0.01
TF(的|D) = 20/200 = 0.1
TF(原理|D) = 3/200 = 0.015

其中我们发现“的”这个词的比重非常高,搜索引擎中一般把这种“的、地、得”这些虚词去掉,不计算其分数。

IDF

Inverse Dcument Frequency, 缩写为IDF。通常叫做“逆文档频率”,其定义为

IDF = log(语料库的文档总数 / 包含该词的文档数 + 1)

可见包含该词的文档数越小,分母就越小,IDF越大;该词越常见,分母就越大,IDF越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。

举例:世界上文档总数位100亿,"Lucene"在1万个文档中出现过,“原理”在2亿个文档中出现过,那么它们的IDF值分别为:

IDF(Lucene) = log(100亿/1万+1) = 19.93
IDF(原理) = log(100亿/2亿+1) = 5.64

“Lucene”重要性相当于“原理”的3.5倍,可见“Lucene”更能表征这篇文档。

TF-IDF

TF-IDF算法的相似度公式就是TF和IDF的加权求和

simlarity = TF1*IDF1 + TF2*IDF2 + ... + TFn*IDFn

上面的例子最终相似度得分为

simlarity(Lucene的原理|D) = 0.01*19.93 + 0 + 5.64*0.015 = 0.2839

其中,“Lucene”占了总分70%的权重,“原理”仅占总分30%的权重。

Lucene中的TF-IDF

Lucene对TF-IDF算法做了适当调整,它的相似度公式为

simlarity = log(numDocs / (docFreq + 1)) * sqrt(tf) * (1/sqrt(length))

各参数含义

  • numDocs: 索引的文档总数量
  • docFreq: 包含关键字的文档数量
  • tf:关键字在一篇文档中出现的次数。
  • length:文档的长度

上面的公式在Lucene打分计算时会被拆分成三个部分:

IDF Score = log(numDocs / (docFreq + 1))
TF Score = sqrt(tf)
fieldNorms = 1/sqrt(length)

log(),sqrt()主要是为了降低分值大小,缩写文档之间分数差距

fieldNorms是对文本长度的归一化(Normalization),为了消除文档长度对分数的影响

所以,上面公式也可以表示成

simlarity = IDF score * TF score * fieldNorms

Lucene在score打分时会遍历匹配到的每篇文档计算每篇文档的score,每篇文档分别计算这三部分分值。最后默认根据score sort。

BM25,下一代的TF-IDF

新版的Lucene不再把TF-IDF作为默认的相关性算法,而是采用了BM25(BM是Best Matching的意思)。BM25是基于TF-IDF并做了改进的算法。先来看下改进之后的BM25算法

simlarity = log(1 + (numDocs - docFreq + 0.5) / (docFreq + 0.5)) * ((k1 + 1) * tf) / (K + tf)

上面的公式在Lucene打分计算时会被拆分成两部分:

IDF Score = log(1 + (numDocs - docFreq + 0.5) / (docFreq + 0.5))
TF Score = ((k1 + 1) * tf) / (K + tf)

这里k1和K下面展开讨论

  • TF项比较

两者公式如下

传统 TF Score = sqrt(tf)
BM25的 TF Score = ((k1 + 1) * tf) / (K + tf)

传统的TF值理论上是可以无限大的。而BM25与之不同,它在TF计算方法中增加了一个常量k1和K,用来限制TF值的增长极限,BM25的 TF Score的范围会控制在[0, k1+1]。其中K

K = k1(1 - b + b*dl/avgdl)

取值k1,b是调节因子,Lucene中默认是k1=2,b=0.75,用户可以自定义。dl为文档的长度,avgdl为所有文档的平均长度。

两者的分布曲线来看,随着tf增大,BM25的TF会接近k1+1,传统的TF会无限变大。

TF中还引入了文档的长度dl,所有文档的平均长度avgdl,这里假设L = dl/avgdl,下面是不同L的条件下,词频对TFScore影响的走势图

从图上可以看到,文档越短,它逼近上限的速度越快,反之则越慢。这是可以理解的,对于只有几个词的内容,比如文章“标题”,只需要匹配很少的几个词,就可以确定相关性。而对于大篇幅的内容,比如一本书的内容,需要匹配很多词才能知道它的重点是讲什么。

关于参数b的作用:公式中L前面有个常系数b,如果把b设置为0,则L完全失去对评分的影响力。b的值越大,L对总评分的影响力越大。

  • IDF项比较

两者公式如下

传统的 IDF Score = log(numDocs / (docFreq + 1))
BM25的 IDF Score = log(1 + (numDocs - docFreq + 0.5) / (docFreq + 0.5))

从分布曲线来看两者走势基本一致。

TF-IDF vs BM25

传统的TF-IDF是自然语言搜索的一个基础理论,它符合信息论中的熵的计算原理,你观察IDF公式会发现,它与熵的公式是类似的。实际上IDF就是一个特定条件下关键词概率分布的交叉熵。

BM25在传统TF-IDF的基础上增加了几个可调节的参数,使得它在应用上更佳灵活和强大,具有较高的实用性。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353