TF-IDF 是什么?从零理解检索算法的核心直觉

15 阅读2分钟

本文面向数学基础薄弱的读者,通过实例和类比,逐步拆解 TF-IDF 公式的每一个细节。


一、TF-IDF 是一个名字,不是减法

第一次看到这个公式,很多人会误以为中间有个减号:

TF-IDF(t,d)=TF(t,d)×IDF(t)\text{TF-IDF}(t, d) = \text{TF}(t, d) \times \text{IDF}(t)

其实 TF-IDF 是算法的名字,横杠只是连字符,就像 "USB-C"、"Wi-Fi" 里的横杠一样。

全称是 Term Frequency–Inverse Document Frequency,中文叫词频–逆文档频率

等号左边是"这个指标叫什么",等号右边是"怎么算出来"——两部分相乘。


二、核心直觉:什么样的词才重要?

假设有 100 篇文章,你要判断哪些词最能代表某篇文章的主题。

  • "的、是、了" — 每篇都有,说明不了任何主题
  • "模型" — 60 篇里出现,有一定区分度
  • "蒸馏" — 只有 3 篇有,非常能区分主题

规律就是:一个词在当前文档出现越多、在整个语料库越少见,它越重要。

TF-IDF 就是把这个直觉变成公式。


三、第一部分:TF(词频)

TF(t,d)=词 t 在文档 d 中出现的次数\text{TF}(t, d) = \text{词 } t \text{ 在文档 } d \text{ 中出现的次数}

  • t = term,词
  • d = document,文档

出现越多,分数越高。非常直观。


四、第二部分:IDF(逆文档频率)

IDF(t)=lnNDF(t)\text{IDF}(t) = \ln \frac{N}{\text{DF}(t)}

  • N = 语料库中文档总数(比如 100 篇)
  • DF(t) = 包含词 t 的文档数量

Inverse(逆) 就是"倒过来"的意思——把 DF 从分子翻到分母。所以:

DF分数趋势
常见词("模型",60篇有)分母大 → 结果小 → 不重要
稀有词("蒸馏",3篇有)分母小 → 结果大 → 很重要

代入数字验证:

DFN/DFIDF = ln(N/DF)
"模型"60100/60 ≈ 1.67ln(1.67) ≈ 0.51
"蒸馏"3100/3 ≈ 33.3ln(33.3) ≈ 3.51

"蒸馏"的 IDF 远高于"模型",说明它区分度更强。


五、为什么要套一个 ln(自然对数)?

先理解对数

对数是指数的逆运算。

你知道 23=82^3 = 8,反过来问"2 的几次方等于 8",答案是 3,写作 log28=3\log_2 8 = 3

自然对数 ln 的底数是数学常数 e2.71828e \approx 2.71828,问的是"e 的几次方等于 x":

lnx=logex\ln x = \log_e x

式子结果
ln1\ln 10
lne\ln e1
ln100\ln 100≈ 4.6

为什么要压缩数值?

不加 ln,极端情况会出问题。

假设语料库有 100 万篇文章,某个生僻词只出现在 1 篇:

NDF(t)=1,000,0001=1,000,000\frac{N}{\text{DF}(t)} = \frac{1{,}000{,}000}{1} = 1{,}000{,}000

这个词的 IDF 直接变成 100 万,哪怕它只出现 1 次,得分也会碾压所有其他正常关键词,排名全乱。

加上 ln 之后:ln(1,000,000)13.8\ln(1{,}000{,}000) \approx 13.8,回到正常量级。

更本质的原因:稀有度的边际价值递减

一个词从"10 篇有"变成"1 篇有",稀有度提升了 10 倍,但它的区分能力并不会真的强 10 倍——只是强了一些。

ln 恰好符合这个直觉:

N/DF不用 ln用 ln
10102.3
1001004.6
100010006.9

越稀有的词确实越重要,但重要程度的提升是边际递减的。ln 就是用来表达这个"递减"的数学工具。


六、附:手算示例(余弦相似度)

TF-IDF 常与余弦相似度配合使用,用于判断两段文本的语义距离。

假设三个句子在简化的 3 维向量空间中的嵌入向量为:

  • "如何养猫" → A = (0.9, 0.5, 0.1)
  • "猫咪饲养指南" → B = (0.8, 0.6, 0.1)
  • "股票投资策略" → C = (0.1, 0.1, 0.9)

余弦相似度公式:

cos(θ)=ABA×B\cos(\theta) = \frac{A \cdot B}{|A| \times |B|}

其中 A|A|向量的模(向量的长度),计算方式为:

A=0.92+0.52+0.12=0.81+0.25+0.01=1.071.03|A| = \sqrt{0.9^2 + 0.5^2 + 0.1^2} = \sqrt{0.81 + 0.25 + 0.01} = \sqrt{1.07} \approx 1.03

注意:这里的"模"是向量长度,不是编程里的"取模(求余数)"运算,两者完全不同。

计算结果:

对比余弦相似度语义关系
A 与 B≈ 0.99非常相似
A 与 C≈ 0.25差异很大

0.99 vs 0.25,清晰地反映了语义距离。


七、TF-IDF 的局限性

最朴素的 TF-IDF 实现有两个缺陷:

  1. 原始词频线性增长 — 出现 10 次是出现 5 次的两倍,但实际重要性未必如此
  2. 没有校正文档长度 — 长文章仅仅因为字数多,就容易获得更高得分

这些问题催生了更现代的改进算法,比如 BM25,它在 TF-IDF 的基础上加入了词频饱和与文档长度归一化。


理解 TF-IDF,是读懂检索增强生成(RAG)和搜索引擎原理的第一步。