跳转到内容

Indri 2005 — 把语言模型、推断网络、结构化查询拼成一个搜索引擎

是什么

Indri 是 UMass Amherst CIIR 实验室 2005 年开源的学术搜索引擎。它做的事是:把当时学术界三个最重要的检索方法——语言模型(Ponte-Croft 1998)、推断网络(Turtle 1991)、结构化查询——拼成一套能跑、能扩、能比对的 C++ 系统。

日常类比:BM25 像一根做好的鱼竿,给你你就能去钓;Indri 像一间渔具作坊,里面有线、轮、钩、漂、铅,你按当天天气和水深自己组一根趁手的。

工程意义:从这一刻起,学术 IR 论文有了一个标准基线——你提个新方法,先用 Indri 把 baseline 跑出来再比,谁也赖不掉。

为什么重要

不理解 Indri,下面这些事都没法解释:

  • 为什么 2005 后十年 SIGIR / TREC 论文里几乎每篇都写”baseline: Indri with default parameters”——它就是当时的”事实标准”
  • 为什么后来的 Galago(2009)、Anserini(2017)一直在向它的查询语言看齐——#combine #weight #1 #uw 这套操作符就是 Indri 立的
  • 为什么”语言模型 + Dirichlet 平滑”现在听起来理所当然——是 Indri 把 Zhai-Lafferty 2001 的公式做进了 production
  • 为什么近 20 年很多论文 baseline 表里”BM25 vs Indri-LM”经常并列——它俩代表两条独立的打分思路

核心要点

Indri 的设计本质是把三种独立的 IR 想法揉到同一个系统里。每一种都来自十几年前的某篇关键论文,Indri 的贡献不是发明,而是让它们能在同一行查询里协作

第一层:语言模型打分(每个文档一个概率分布)

把每篇文档 D 想成一个”语言生成器”——它有自己用词的概率分布 p(w|D)。一个查询 Q 的得分就是”D 这个生成器吐出 Q 这串词的概率”。这就是 Ponte-Croft 1998 的核心想法。

但有问题:D 没出现的词,p(w|D) = 0,整个查询得分变 0。要平滑——Indri 默认用 Dirichlet 平滑

p(w | D) = (tf + μ · p(w|C)) / (|D| + μ)

p(w|C) 是这个词在整个语料里的概率(背景模型),μ 是平滑强度(Indri 默认 2500)。短文档 μ 占比高、长文档 tf 占比高——这个比例自适应,比 BM25 的固定参数 b 优雅。

第二层:推断网络(把多个证据组合起来)

Turtle 1991 的想法:把”用户的信息需求”当成一个贝叶斯网络的根节点 I,文档 D 通过若干条边给 I 提供证据。每条边是一个查询操作符——#combine 是”几个证据加权平均”、#weight 是”加权和”、#wand(weighted AND)是”全部都需要”.

这个网络结构带来的好处:你可以嵌套。比如”想找讲苹果手机的文档” = #combine(#syn(iphone "apple phone") #1(retina display))——里面 #syn 是同义词、#1 是要求两词紧邻成短语。每个子节点自己算分,往上传给父节点,最终聚合到 I。

第三层:结构化查询语言(让用户能说复杂的话)

Indri Query Language 是这套系统的”用户面”。常用操作符:

  • #combine(a b c) — 三个词加权(默认等权)
  • #weight(0.7 a 0.3 b) — 显式给权重
  • #1(new york) — 要求”new”和”york”紧邻成有序短语
  • #uw5(privacy data) — 要求两词在 5 词窗口内(无序)
  • #syn(car automobile) — 看作同义
  • #filter(date>2020 ...) — 加约束
  • 字段查询:title:(deep learning) — 只在标题字段命中

这些不是花架子。它让一个研究员能用一行查询把”多词短语 + 同义词 + 字段限制”说清楚,等价于 BM25 系统里要写几十行 rerank 代码。

第四层:开源 C++ + 索引压缩 + 分布式

不是研究 demo,是能扛 TB 级语料的工程系统。Strohman(一作)写了大量底层代码——倒排索引压缩、内存映射、并行查询执行。后来 TREC Terabyte / Web Track 多支队伍直接拿 Indri 跑 25TB 数据。

实践案例

案例 1:默认 LM 查询是什么样

#combine(machine learning)

这是最简单的 Indri 查询。系统做的事:

  1. 拆 query 成两个词
  2. 每个词用 Dirichlet 平滑算 p(w|D)
  3. #combine 把两个对数概率加起来
  4. 按总分排序

效果上和”BM25 跑同一个 query”很接近,但理论基础完全不同——Indri 是在算概率,BM25 是在拟合曲线。

案例 2:结构化查询的威力

要找”讲 React Server Components 的官方文档”:

#weight(0.6 #1(react server components)
0.3 site:react.dev
0.1 #combine(rsc streaming))
  • #1(...) 强制三个词按这个顺序紧邻
  • site:react.dev 字段过滤
  • 第三段是”扩展词”,给一些权重补召回

这种写法在纯 BM25 + 字段倒排里要拼好几个子查询,Indri 一行搞定。

案例 3:伪相关反馈(Relevance Model)

#combine[lavrenko_rm3]( original_query )

Indri 内置 Lavrenko-Croft 2001 的 RM3——先用原 query 取 top-k,从这些文档里抽高频词扩展原 query,再查一次。一个开关搞定,不用自己写。

踩过的坑

  1. μ 默认 2500 不是金科玉律——它是 TREC 新闻语料调出来的。Web 文档(短)和书(长)该用不同的 μ。很多人忘改,baseline 不公平。
  2. #combine 默认平均权重,不是 BM25 那种 IDF 加权——稀有词和常见词权重一样,需要显式 #weight 或开 PRF。
  3. C++ 11 之前的代码——内存管理踩雷多。2010 年代后期社区基本不维护,只跑老论文复现。
  4. 不是 Lucene 兼容——索引格式独有。想从 Indri 迁到 Anserini/Pyserini 要重建索引。
  5. 结构化查询语言强大但难学——文档稀薄、报错友好度差。新人 80% 时间在调 query 语法。

适用 vs 不适用场景

适用

  • 复现 2005-2015 年学术 IR 论文(很多 baseline 直接给 Indri 配置文件)
  • 教学:演示语言模型 vs BM25 的差异
  • 需要复杂结构化查询的小到中等规模实验(百万级文档以下舒服)

不适用

  • 工业生产搜索 → 用 Elasticsearch / OpenSearch / Vespa(社区、生态、运维都成熟)
  • 现代神经检索基线 → 用 Pyserini(Lucene + Python,Anserini 团队维护)
  • TB 级实时索引 → Indri 静态索引模型不适合频繁更新

历史小故事(可跳过)

  • 1992 年:Croft 在 UMass 做出 INQUERY,第一次把推断网络做进检索系统。CIIR 实验室成立。
  • 1998 年:Croft 的学生 Ponte 提出”用语言模型做检索”,开启 LM-IR 路线。
  • 2001 年:Zhai-Lafferty 把 Dirichlet 平滑系统化;同年 CIIR 联合 CMU 发布 Lemur 工具包。
  • 2005 年:Strohman 主写、Metzler 设计查询语言、Turtle 把 1991 的推断网络代码捐进来、Croft 挂顾问,做出 Indri,是 Lemur 的”产品级版本”。
  • 2009 年起:Strohman 离开学术界后,Galago(Java 重写)接棒;2017 年 Anserini 用 Lucene 重做了一遍,Indri 逐渐退出主流。

学到什么

  1. 检索系统的”配方”是分层的——打分(LM/BM25)+ 组合(推断网络)+ 用户接口(query 语言)+ 引擎(索引/分布式),每层独立可换。
  2. 学术系统的最大贡献不是性能而是基线——Indri 让所有人有了同一个对照组,IR 论文从此可比。
  3. 理论”美”不等于工程”能跑”——2-Poisson、推断网络都美了 10 年才有人做出能跑的版本。论文到落地的路一般 15 年。
  4. 同一时代会有两条平行路线——BM25(拟合曲线)和 LM-IR(生成模型)几乎同步发展,谁也没杀死谁,今天都活着。

延伸阅读

  • 项目主页:Lemur Project / Indri(源码、文档、教程)
  • Croft / Metzler / Strohman 的教材:《Search Engines: Information Retrieval in Practice》(用 Indri 当主线讲所有 IR 技术)
  • okapi-bm25-1994 —— BM25,Indri 的另一条平行路线
  • salton-vsm-1975 —— 向量空间模型,比 LM/BM25 更早的检索打分思路
  • google-1998 —— PageRank,Web 检索把”链接”也加入证据网络

关联

  • okapi-bm25-1994 —— BM25:单一打分公式 vs Indri:可组合框架
  • salton-vsm-1975 —— VSM:第一代向量打分,Indri 之前的主流
  • google-1998 —— Google:把链接图当额外证据,启发 Indri 字段证据
  • simrank-2002 —— 同期 IR 研究的另一条线(结构相似度)