目录
信息检索核心原理
- 信息检索 IR 核心原理
- IR 的基本对象与术语
- 文档、语料、字段
- Document(文档):检索的基本单位
- Fields(字段):title、body、tags
- Tokenization/Analysis (分词与分析链)
- 典型分析链
- 字符过滤(去 HTML、统一全角半角、大小写)
- Tokenizer(切词:英文按空格/规则,中文依赖分词器)
- Token Filter
- stopword(停用词)
- stemming/lemmatization(词干/词形还原)
- synonym(同义词)
- ngram(前缀/模糊)
- 倒排索引相关名词
- Term(词项):token 的规范化结果
- Posting list:某 term 出现在那些 doc 中的列表
- DocID:文档编号
- tf(term frequency):该词在 doc 内出现的次数
- df(document frequency):包含该词的 doc 数
- idf(inverse document frequency):词的区分能力
- 相关性:从 TF-IDF 到 BM25
- TF-IDF 的直觉
- 核心思想
- 一个词在文档里出现的越多(tf 越大)-> 越相关
- 一个词在整个语料越稀有(df 越小/idf 越大)-> 越能区分文档
- tf = count(t in d)
- idf = log(N/df)
- TF-IDF 容易出现两类不稳
- tf 线性增长导致刷词得分优势
- 文档长短差异导致长文天然占优势
- BM25:工程默认答案
- 核心思想
- tf 饱和:词出现 1->2 词提升很大,20->21 词提升小(防刷词)
- 长度归一化:长文不会因为词多天然优势
- 得分计算
- score(d, q) = Σ[ idf(t) * ( tf*(k1+1) / ( tf + k1*(1 - b + b*|d|/avgdl ))) ]
- k1:控制 tf 饱和速度
- b:控制长度归一化强度
- |d|/avgdl:文档长度与平均长度的比例
- 字段权重
- 现实检索几乎都是多字段:title/body/tags
- 常见做法:对字段分别计算 BM25,再加权组合
- 查询模型
- 布尔检索
- AND/OR/NOT,精准过滤
- 工程上常用于 filter(不参与打分)而非主排序)
- filter 可缓存,query 参与打分不易缓存
- 向量空间模型
- doc/query 看作高维向量,维度是 term,相似度用 cosine
- sim = cos(q,d)
- 概率检索
索引结构与写入链路
- 索引结构与写入链路
- ES 的索引
- InvertedIndex(倒排):解决词->文档的快速检索
- Doc Values(列式):解决按字段排序/聚合/脚本读取的高效访问
- 倒排负责召回和打分;doc values 负责排序/聚合/分面
- 倒排索引的组成:字典 + posting
- Term Dictionary
- 存储所有 Term 的集合,能够快速定位某个 term 对应的 posting list
- Lucence 用 FST 等结构做压缩与快速查找
- Posting List(倒排表)
- docID 列表:包含该 term 的文档
- freq(tf):该 term 在 doc 中出现的次数
- positions(位置):term 在 doc 中的位置
- offsets(字符便宜):高亮需要(从哪里到哪里)
- Doc Values
- 是什么
- 按 docId 顺序存储某个字段的值(列式)
- price、timestamp、category、keyword 字段
- 排序聚合为什么不用倒排
- 倒排是 term -> doc,适合检索;排序聚合需要 doc->field value
- doc values 提供了高效的按照 doc 读取字段值,同时适合磁盘顺序访问 + OS page cache
- Segment
- Segment 是什么
- 一个 index 由多个 segment 组成
- 每个 segment 内部包含:倒排、doc values、stored fields、norms 等文件
- segment 一旦写出就不可变
- 不可变的好处
- 并发读及其简单:读线程不需要大锁,数据结构稳定
- 缓存友好:文件内容不会变,OS cache 命中更稳定
- 写入快:写在新 segment;避免原地更新导致随机写/锁竞争
- 崩溃恢复快