Xapian实现Simple BM25F

news/2024/7/3 14:37:00 标签: string, integer, query, database, extension, iterator

SimpleBM25F是BM25F的基础拓展版本,主要用于多个域的拓展,感兴趣的可以看《Simple BM25 Extension to Multiple Weighted Fields》。

主要观点:按照权重将不同域重复相应次数,拼成无结构的混合文本桶,然后只计算一次BM25得分。

而之前很多人采用的各个域先计算不同的BM25,再线性组合的做法,则破坏了词项独立性而效果很差。

传统:bm25.cpp

#四号程序员, http://www.coder4.com
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <xapian.h>
#include <iostream>
  
using namespace std;
  
#define DOC1_TITLE string">"这 是 一条 新闻 "
  
#define DOC2_TITLE string">"这 是 一条 男篮 新闻 "
  
#define DOC1_CONTENT " 70 69 , 这是 男篮 亚锦赛 历史上 的 最小 分 差 比赛 , 笑 到 最后 的是 东道主 中国队 。 可以说 , 这是 一次 最 惊险 的 胜利 ; 也可 以
  说 , 这是 中国男篮 最 幸运 的 结局 。终 >  场 哨 响 , 中国队 主教练 邓 华德 和 篮管中心 副主任 胡 加时 紧紧拥抱 在一 起 , 两人 都 激动 得 热泪盈眶 —— 中
队 赢了 , 赢得 很 庆幸 。 男篮 "
  
#define DOC2_CONTENT " 70 69 , 这是 男篮 亚锦赛 历史上 的 最小 分 差 比赛 , 笑 到 最后 的是 东道主 中国队 。 可以说 , 这是 一次 最 惊险 的 胜利 ; 也可 以
  说 , 这是 中国男篮 最 幸运 的 结局 。终 >  场 哨 响 , 中国队 主教练 邓 华德 和 篮管中心 副主任 胡 加时 紧紧拥抱 在一 起 , 两人 都 激动 得 热泪盈眶 —— 中
队 赢了 , 赢得 很 庆幸 。 "
  
#define INDEX_PATH string">"./index_data"
  
#define F_DOCID 1
  
int main()
{
         try
         {
                 //Text to be indexed
                 string doc1_text(DOC1_TITLE);
                 doc1_text += DOC1_CONTENT;
                 string doc2_text(DOC2_TITLE);
                 doc2_text += DOC2_CONTENT;
  
                 //Open an Database for write
                 Xapian::WritableDatabase db(string(INDEX_PATH), Xapian::DB_CREATE_OR_OPEN);
  
                 //Prepare TermGenerator, just split word by space, not chinese analysis
                 Xapian::TermGenerator indexer;
  
                 //Make && Index Doc1
  
                 Xapian::Document doc1;
                 doc1.add_value(F_DOCID, string( string">"doc1" ));
                 indexer.set_document(doc1);
                 indexer.index_text_without_positions(doc1_text);
                 db.add_document(doc1);
  
                 //Make && Index Doc2
                 Xapian::Document doc2;
                 doc2.add_value(F_DOCID, string( string">"doc2" ));
                 indexer.set_document(doc2);
                 indexer.index_text_without_positions(doc2_text);
                 db.add_document(doc2);
  
                 //Flush to disk
                 db.commit();
         }
         catch ( const Xapian::Error &e)
         {
                 cout << e.get_description() << endl;
         }
         return 0 ;
}

结果,由于doc1的content多一个“男篮”,所以比doc2得分高,doc1排第一。

1
2
3
4
5
Query is Xapian::Query(男篮:(pos=1))
2 results found
  
0: doc1
1: doc2

再看Simple BM25F,注意权重使用函数的第2个参数wdf就行了:


1
2
3
4
void Xapian::TermGenerator::index_text_without_positions    (   const Xapian::Utf8Iterator &    itor,
Xapian::termcount   wdf_inc = 1,
const std::string &     prefix = std::string()
)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <xapian.h>
#include <iostream>
  
using namespace std;
  
#define DOC1_TITLE string">"这 是 一条 新闻 "
  
#define DOC2_TITLE string">"这 是 一条 男篮 新闻 "
  
#define DOC1_CONTENT " 70 69 , 这是 男篮 亚锦赛 历史上 的 最小 分 差 比赛 , 笑 到 最后 的是 东道主 中国队 。 可以说 , 这是 一次 最 惊险 的 胜利 ; 也可 以
  说 , 这是 中国男篮 最 幸运 的 结局 。终 >  场 哨 响 , 中国队 主教练 邓 华德 和 篮管中心 副主任 胡 加时 紧紧拥抱 在一 起 , 两人 都 激动 得 热泪盈眶 —— 中
队 赢了 , 赢得 很 庆幸 。 男篮 "
  
#define DOC2_CONTENT " 70 69 , 这是 男篮 亚锦赛 历史上 的 最小 分 差 比赛 , 笑 到 最后 的是 东道主 中国队 。 可以说 , 这是 一次 最 惊险 的 胜利 ; 也可 以
  说 , 这是 中国男篮 最 幸运 的 结局 。终 >  场 哨 响 , 中国队 主教练 邓 华德 和 篮管中心 副主任 胡 加时 紧紧拥抱 在一 起 , 两人 都 激动 得 热泪盈眶 —— 中
队 赢了 , 赢得 很 庆幸 。 "
  
#define WEIGHT_TITLE 2
  
#define WEIGHT_CONTENT 1
  
#define INDEX_PATH string">"./index_data"
  
#define F_DOCID 1
  
int main()
{
         try
         {
                 //Open an Database for write
                 Xapian::WritableDatabase db(string(INDEX_PATH), Xapian::DB_CREATE_OR_OPEN);
  
                 //Prepare TermGenerator, just split word by space, not chinese analysis
                 Xapian::TermGenerator indexer;
                 //Make && Index Doc1
                 Xapian::Document doc1;
                 doc1.add_value(F_DOCID, string( string">"doc1" ));
                 indexer.set_document(doc1);
                 indexer.index_text_without_positions(string(DOC1_TITLE), WEIGHT_TITLE); // WEIGHT_XX is integer for tf
                 indexer.index_text_without_positions(string(DOC1_CONTENT), WEIGHT_CONTENT); // WEIGHT_XX is integer for tf
                 db.add_document(doc1);
  
                 //Make && Index Doc2
                 Xapian::Document doc2;
                 doc2.add_value(F_DOCID, string( string">"doc2" ));
                 indexer.set_document(doc2);
                 indexer.index_text_without_positions(string(DOC2_TITLE), WEIGHT_TITLE); // WEIGHT_XX is integer for tf
                 indexer.index_text_without_positions(string(DOC2_CONTENT), WEIGHT_CONTENT); // WEIGHT_XX is integer for tf
                 db.add_document(doc2);
  
                 //Flush to disk
                 db.commit();
         }
         catch ( const Xapian::Error &e)
         {
                 cout << e.get_description() << endl;
         }
         return 0 ;
}

再看结果,由于title重复了两次,所以doc2多含了一个tf的“男篮”,因此doc2排1:


1
2
3
4
5
Query is Xapian::Query(男篮:(pos=1))
2 results found
  
0: doc2
1: doc1

您可能也喜欢如下文章:

  1. 学习Xapian(2) – 拼写校正
  2. 学习Xapian(4) – Faceting Search(Filter / 过滤)
  3. 学习Xapian(3) – 同义词的查询拓展
  4. 学习Xapian(1) – 基础的建索引和搜索

http://www.niftyadmin.cn/n/1534968.html

相关文章

3-Linux 进程中的某个线程占用时间

在比较大型的项目中&#xff0c;通常都会使用多线程技术&#xff0c;而且通常是多人合作开发&#xff0c;各方自测OK之后&#xff0c;整合在一起往往会出现一些问题&#xff0c;CPU使用率过高就是其中之一。如何在不熟悉所有模块代码的情况下&#xff0c;快速的定位到具体哪一个…

spring学习十二 application/x-www-form-urlencoded还是application/json

application/x-www-form-urlencoded还是application/json get、 POST 用哪种格式&#xff1f; 后台如何得到这些值&#xff1f; 如何用ajax 或者是 postman 发送这些 请求&#xff1f; 11.2.3 执行REST动作: A) GET、POST方式提时&#xff0c; 根据request header Content-…

25、shell编程—locate、whereis和which

文章目录locatewhereiswhichlocate locate 命令在数据库中进行查找文件&#xff0c;locate默认的是部分匹配 创建的文件默认会在第二天记录在/var/lib/mlocate.db 下面&#xff0c;所以创建完文件想立即生效&#xff0c;可以执行updatedb命令 实例 locate my.cnf/etc/my.cnf /…

4-Linux 内存泄漏工具

1、mtrace 应用环境&#xff1a;Linux GLIBC 编程语言&#xff1a;C 使用方法&#xff1a; 包含头文件mcheck.h&#xff0c;定义环境变量MALLOC_TRACE为输出文件名&#xff0c;程序开始时调用mtrace()即可。 结果输出&#xff1a;用户指定的文件 设计思路&#xff1a; 为m…

深度学习资料汇总

个人认为还是看论文来的比较实在 [1] 深度学习书籍pdf版本 [2] 深度学习原版英文书籍 转载于:https://www.cnblogs.com/hellokittyblog/p/9128374.html

26、shell编程—grep语法、以及grep转义字符

文章目录1.grep 和 find的区别2.grep用法3.egrep 和 grep区别4.grep转义字符汇总1.grep 和 find的区别 grep时查找文件内容find是查找文件的 2.grep用法 第一种形式&#xff1a;grep [option] [pattern] [file1,file2...] 第二种形式&#xff1a;command | grep [option] [p…

0-Linux coredump捕获分析

1.制作debug-root commit a4a3b5ba5a7bdb3fb98028793d62f37788c0790a config: CONFIG_DEBUG use debug rootfs, sstrip real rootfs9ad4d66b7aa27f7ee42281466662d51044001278debug: add debug-root for debug coredump and panicVIM 系统编译加上-g3,在strip之前,将这些文文件…

27、shell编程—sed工作模式以及选项

文章目录1.sed工作模式2.sed语法格式3.sed选项option3.1.option之-n3.2.option之-e3.3.option之-f3.4.option之-r3.5.option之-i1.sed工作模式 sed:流编辑器&#xff0c;对标准输出或文件进行逐行处理 大白话就理解一个文件编辑器&#xff0c;对文件里面的内容&#xff0c;一行…