信息检索与表示基础
1. 信息检索的基本任务
信息检索(Information Retrieval)的核心任务是:给定查询
形式化地:给定查询向量
这看似简单,但关键问题在于:文本是离散的符号序列,而相似度需要数值计算。因此,“表示”(representation)成为连接查询与文档之间的桥梁——将文本映射到可计算的空间中,使得语义相近的文本在该空间中距离更近。
2. 表示方式:从词袋到稠密向量
2.1 词袋模型(Bag of Words, BoW)
词袋模型是最简单的文本表示方式。它忽略语法和语序,将文档表示为词项的多重集(multiset):
其中
缺陷:所有词项被平等对待,“机器学习”和”学习机器”在词袋模型中完全等价,无法表达语义差异。
2.2 TF-IDF
TF-IDF(Term Frequency - Inverse Document Frequency)是对词袋的加权改进,目的是让罕见的词项拥有更高权重:
TF(词频):词项在文档中出现的频率,常见形式有:
- 原始计数:
- 对数平滑:
- 归一化:
IDF(逆文档频):词项在整个语料中的稀有程度:
其中
IDF 的直观含义是:一个词如果几乎出现在所有文档中,它就没有区分能力;一个词如果只在少量文档中出现,它对区分文档很有用。
TF-IDF 最终权重:
文档向量为
2.3 BM25
BM25(Best Matching 25)是基于概率模型的检索函数,是 Lucene(Elasticsearch)默认使用的排序算法。它在 TF-IDF 基础上引入了文档长度归一化,解决了长文档天然包含更多词项的问题。
BM25 的评分函数:
其中:
:词频饱和参数,控制词频增长的平滑速度 :长度归一化参数,控制文档长度对得分的影响程度 :文档长度(词项总数) :语料平均文档长度
核心思想:词频收益会饱和(不会无限线性增长),且短文档中命中某词比长文档中命中更具区分度。
2.4 稠密向量表示(Dense Embedding)
词袋和 TF-IDF 产生的是稀疏向量(大多数维度为零),而稠密表示将文档映射到低维连续空间中:
稠密向量的优势在于:
- 语义编码:捕获词语之间的语义关系(“电脑”和”计算机”在稀疏模型中毫无关系,在稠密模型中高度相关)
- 维度压缩:300-768 维的稠密向量即可表示全文档语义,比词袋的万维稀疏向量更紧凑
- 统一空间:查询和文档共享同一个编码器,映射到同一语义空间,直接用余弦相似度即可度量
3. 向量空间模型与相似度度量
3.1 向量空间模型(Vector Space Model, VSM)
向量空间模型将文档和查询都表示为向量,相似度即为向量空间中的距离度量。
设查询向量
余弦相似度(Cosine Similarity):
余弦相似度衡量的是方向而非量级,对向量长度不敏感,适用于文本长度差异较大的场景。
点积(Dot Product):
点积同时考虑方向和量级,对向量范数敏感。当向量经过归一化后,点积等价于余弦相似度。
欧氏距离(Euclidean Distance):
欧氏距离是绝对距离度量,在向量归一化条件下,与余弦相似度呈单调递减关系(但不等价)。
三者差异总结:
| 度量方式 | 敏感度 | 适用场景 |
|---|---|---|
| 余弦相似度 | 只管方向,不管量级 | 文档长度差异大,但语义重要性一致 |
| 点积 | 同时管方向和量级 | 向量已归一化,或需要放大高频词影响 |
| 欧氏距离 | 绝对距离 | 需要考虑向量绝对位置的场景 |
4. 稀疏检索 vs 稠密检索
4.1 稀疏检索的优势与局限
优势:
- 可解释性强:命中的词项可以直接展示
- 精确匹配能力强:对专有名词、术语、数字、IDs 等稀疏检索高度可靠
- 无需训练:TF-IDF、BM25 无需任何训练数据,直接可用于新语料
- 计算快速:稀疏向量可使用倒排索引,BM25 评分复杂度低
局限:
- 无法处理语义相似但词面不同的查询(如”电脑”vs”计算机”)
- 维度高(词汇表规模),存储开销大
- 词项独立假设,忽略词序和上下文
擅长场景:专有名词检索、代码搜索、精确术语匹配、已知关键词搜索。
4.2 稠密检索的优势与局限
优势:
- 语义理解:捕获同义词、语义关联
- 维度压缩:128-1024 维即可有效表示语义
- 跨语言表示:多语言编码器可使不同语言共享语义空间
局限:
- 需要训练数据和计算资源
- 对专有名词、罕见实体的精确匹配能力弱于稀疏检索
- 黑盒化,可解释性差
- 索引存储稠密向量而非稀疏词项
擅长场景:语义搜索、开放式问答、相似文档召回、跨语言检索。
4.3 对比总结
| 维度 | 稀疏检索(BM25) | 稠密检索(Embedding) |
|---|---|---|
| 表示维度 | 高维稀疏(词汇表规模) | 低维稠密(128-1024) |
| 语义能力 | 词面匹配 | 语义理解 |
| 精确匹配 | 强 | 弱 |
| 泛化能力 | 无 | 强 |
| 索引结构 | 倒排索引 | ANN 索引 |
| 计算成本 | 低 | 中-高 |
| 可解释性 | 高 | 低 |
| 无需训练 | 是 | 否(需预训练模型) |
| 典型工具 | Elasticsearch、Lucene | Milvus、Pinecone、FAISS |
5. 为什么表示质量决定召回上限
检索系统的”召回上限”由表示质量决定,这一结论来自信息检索的基本约束:
如果查询
recall@K 的上限近似为:
其中
这解释了为什么:
- 稀疏检索的召回上限:受词面匹配约束,“心脏”无法召回讨论”心血管”但不包含”心脏”一词的文档
- 稠密检索的召回上限:受编码器语义能力的约束,如果嵌入模型对特定领域语义建模不足,相关文档仍会遗漏
- 混合检索的必要性:稀疏和稠密各有盲区,组合使用可覆盖更广泛的召回空间
6. 查询和文档的统一语义空间
检索系统要求查询和文档必须映射到同一语义空间,否则相似度度量毫无意义。
设文档编码器为
并要求
常见做法:
- 共享编码器:
,如 Sentence-BERT 在相同数据集上训练两个编码器共享权重 - 独立编码器 + 对齐训练:分别训练
和 ,但通过对比学习使其语义空间对齐 - 跨语言对齐:使用多语言模型,使不同语言的查询和文档映射到共享空间
工程警告:如果
7. 工程流程:文本预处理
7.1 文本预处理的完整流程
原始文本 → 分句 → 分词/词法分析 → 停用词过滤 → 词形还原/归一化 → 向量化
- 分句:按句号、换行符、段落边界切分文档。保留句子边界信息有助于后续 chunking。
- 分词:中文需要分词(jieba、HanLP),英文可按空格切分。分词质量直接影响词袋表示。
- 词形还原/归一化:英文大小写归一化、词干提取(stemming)、词形还原(lemmatization)。中文需做繁简转换、同义词归一。
- 停用词过滤:去除”的""是""and""the”等高频无意义词,降低噪声。但注意:停用词表需根据领域调整,搜索场景中某些停用词可能是检索词。
- 向量化:将处理后的文本输入编码器,得到向量或稀疏权重。
7.2 词项索引 vs 向量索引
| 维度 | 词项索引(倒排索引) | 向量索引(ANN) |
|---|---|---|
| 索引结构 | 词项 → 文档列表 | 向量 → 聚类/图结构 |
| 检索方式 | 词项匹配 → 候选集 | 近似最近邻搜索 |
| 典型工具 | Elasticsearch、Lucene | FAISS、Milvus、HNSW |
| 适用场景 | 精确词匹配、术语检索 | 语义相似、跨语言检索 |
| 索引更新 | 追加式更新较慢 | 需重建或增量策略 |
7.3 检索系统的典型流程
用户查询 → 查询理解 → 查询编码 → 召回(Recall)→ 过滤(Filter)→ 排序(Ranking)→ 返回结果
- 查询理解:解析查询意图,提取关键实体,做查询扩展/改写
- 查询编码:将查询文本转为向量(稀疏或稠密)
- 召回:从全量文档中快速找出候选集(通常返回 100-1000 个)
- 过滤:去除低质量、质量不符、时效性不符的候选
- 排序:对候选集进行精细排序,决定最终 top-k 输出
附录 A:稀疏检索 vs 稠密检索对比表
| 特性 | 稀疏检索(BM25) | 稠密检索(Embedding) |
|---|---|---|
| 表示方式 | 高维稀疏向量 | 低维稠密向量 |
| 语义理解 | 无(词面匹配) | 有(语义编码) |
| 精确匹配 | 强 | 弱 |
| 同义词处理 | 差 | 好 |
| 计算效率 | 高 | 中等 |
| 索引大小 | 大(词表维度) | 小(低维向量) |
| 可解释性 | 高 | 低 |
| 训练数据需求 | 无 | 有(需预训练/微调) |
| 专有名词召回 | 强 | 弱(依赖训练覆盖) |
| 跨语言能力 | 无 | 有(多语言模型) |
| 典型场景 | 术语搜索、代码搜索 | 语义问答、文档推荐 |
| 代表工具 | Elasticsearch | FAISS, Milvus |
附录 B:信息检索系统基础流程图
┌─────────────────────────────────────────────────────────┐
│ 文档处理阶段 │
├─────────────────────────────────────────────────────────┤
│ 原始文档 → 分句 → 分词/归一化 → 编码 → 向量/稀疏表示 │
│ ↓ │
│ 建立索引(倒排/ANN) │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 查询处理阶段 │
├─────────────────────────────────────────────────────────┤
│ 用户查询 → 查询解析 → 查询编码 → 向量/稀疏表示 │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 检索与排序阶段 │
├─────────────────────────────────────────────────────────┤
│ 召回(Recall) → 过滤(Filter) → 排序(Rank) │
│ ↓ ↓ ↓ │
│ ANN/倒排索引 规则/质量 模型重排 │
│ 候选集100-1K 过滤噪音 最终Top-K │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 结果输出阶段 │
├─────────────────────────────────────────────────────────┤
│ 返回 Top-K 文档 + 相关性分数 │
└─────────────────────────────────────────────────────────┘
关键设计决策:
- 召回阶段追求高 recall(不遗漏相关文档),容忍一定噪声
- 排序阶段追求高 precision(不引入无关文档),精细化打分
- 两阶段分离使系统可独立优化每个环节