Xapian实现Simple BM25F

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 "这 是 一条 新闻 "
  
#define DOC2_TITLE "这 是 一条 男篮 新闻 "
  
#define DOC1_CONTENT " 70 69 , 这是 男篮 亚锦赛 历史上 的 最小 分 差 比赛 , 笑 到 最后 的是 东道主 中国队 。 可以说 , 这是 一次 最 惊险 的 胜利 ; 也可 以
  说 , 这是 中国男篮 最 幸运 的 结局 。终 >  场 哨 响 , 中国队 主教练 邓 华德 和 篮管中心 副主任 胡 加时 紧紧拥抱 在一 起 , 两人 都 激动 得 热泪盈眶 —— 中
队 赢了 , 赢得 很 庆幸 。 男篮 "
  
#define DOC2_CONTENT " 70 69 , 这是 男篮 亚锦赛 历史上 的 最小 分 差 比赛 , 笑 到 最后 的是 东道主 中国队 。 可以说 , 这是 一次 最 惊险 的 胜利 ; 也可 以
  说 , 这是 中国男篮 最 幸运 的 结局 。终 >  场 哨 响 , 中国队 主教练 邓 华德 和 篮管中心 副主任 胡 加时 紧紧拥抱 在一 起 , 两人 都 激动 得 热泪盈眶 —— 中
队 赢了 , 赢得 很 庆幸 。 "
  
#define INDEX_PATH "./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( "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( "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 "这 是 一条 新闻 "
  
#define DOC2_TITLE "这 是 一条 男篮 新闻 "
  
#define DOC1_CONTENT " 70 69 , 这是 男篮 亚锦赛 历史上 的 最小 分 差 比赛 , 笑 到 最后 的是 东道主 中国队 。 可以说 , 这是 一次 最 惊险 的 胜利 ; 也可 以
  说 , 这是 中国男篮 最 幸运 的 结局 。终 >  场 哨 响 , 中国队 主教练 邓 华德 和 篮管中心 副主任 胡 加时 紧紧拥抱 在一 起 , 两人 都 激动 得 热泪盈眶 —— 中
队 赢了 , 赢得 很 庆幸 。 男篮 "
  
#define DOC2_CONTENT " 70 69 , 这是 男篮 亚锦赛 历史上 的 最小 分 差 比赛 , 笑 到 最后 的是 东道主 中国队 。 可以说 , 这是 一次 最 惊险 的 胜利 ; 也可 以
  说 , 这是 中国男篮 最 幸运 的 结局 。终 >  场 哨 响 , 中国队 主教练 邓 华德 和 篮管中心 副主任 胡 加时 紧紧拥抱 在一 起 , 两人 都 激动 得 热泪盈眶 —— 中
队 赢了 , 赢得 很 庆幸 。 "
  
#define WEIGHT_TITLE 2
  
#define WEIGHT_CONTENT 1
  
#define INDEX_PATH "./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( "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( "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) – 基础的建索引和搜索
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值