这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记。
本篇笔记对搜索引擎项目构建索引与计算query-文档关联度的BM25算法进行逻辑解析以及实现方式的介绍。
BM25
算法整体实现步骤
-
BM25算法用于计算一条搜索文本(可分为多个分词)与一个文档的匹配程度。
-
算法可分为三部分:
- 分词权重
- 分词和一个文档的关联度
- 分词与搜索文本的关联度(可选,对于长query需要)
文档解析: 分词文档关联度和 分词 权重计算
-
解析文档 计算中间表参数
- 输入:文档
- 计算:调用分词接口得到分词和分词在该文档中的词频
- 存储:
- 中间表1 word_temp {indexKey:分词, tempData:[ {doc_id, word_freq}]}
- 中间表2 doc_length (doc_id, doc_len)
- 回表汇总 计算索引数据:
-
输入:
- 中间表1 word_temp
- 中间表2 doc_length
-
计算:
- 分词权重:
- 读取doc_length得到总文档数
- 读取word_temp得到包含当前分词的文档个数
- 分词文档关联度
- 读取word_temp得到分词在该文档中的词频
- 读取doc_length得到当前文档长度
- 读取doc_length得到所有文档平均长度
- corr:
- corr = 分词权重*分词文档关联度
- 根据上面计算得到的关联度,从高到低排序
- 分词权重:
-
存储
- word_doc_corr (结果表) 分词:[doc_id, corr]
-
查询排序: 加权计算 与 排序
实现逻辑:
- 输入:
- map[分词,query中该分词词频]
- 解析query得到
- list[分词:[doc_id, corr]]
- 查索引表得到,corr是分词权重*分词文档关联度(ordered)
- 计算
- 对每个list根据关联度快排
- 遍历所有分词的list,对每个list里的每个doc,在hashmap的里加上其根据分词query关联度调整过的权重
- 对所有doc排序
- 输出:ordered list,一个整体排完序的list