本文面向数学基础薄弱的读者,通过实例和类比,逐步拆解 TF-IDF 公式的每一个细节。
一、TF-IDF 是一个名字,不是减法
第一次看到这个公式,很多人会误以为中间有个减号:
其实 TF-IDF 是算法的名字,横杠只是连字符,就像 "USB-C"、"Wi-Fi" 里的横杠一样。
全称是 Term Frequency–Inverse Document Frequency,中文叫词频–逆文档频率。
等号左边是"这个指标叫什么",等号右边是"怎么算出来"——两部分相乘。
二、核心直觉:什么样的词才重要?
假设有 100 篇文章,你要判断哪些词最能代表某篇文章的主题。
- "的、是、了" — 每篇都有,说明不了任何主题
- "模型" — 60 篇里出现,有一定区分度
- "蒸馏" — 只有 3 篇有,非常能区分主题
规律就是:一个词在当前文档出现越多、在整个语料库越少见,它越重要。
TF-IDF 就是把这个直觉变成公式。
三、第一部分:TF(词频)
- t = term,词
- d = document,文档
出现越多,分数越高。非常直观。
四、第二部分:IDF(逆文档频率)
- N = 语料库中文档总数(比如 100 篇)
- DF(t) = 包含词 t 的文档数量
Inverse(逆) 就是"倒过来"的意思——把 DF 从分子翻到分母。所以:
| 词 | DF | 分数趋势 |
|---|---|---|
| 常见词("模型",60篇有) | 大 | 分母大 → 结果小 → 不重要 |
| 稀有词("蒸馏",3篇有) | 小 | 分母小 → 结果大 → 很重要 |
代入数字验证:
| 词 | DF | N/DF | IDF = ln(N/DF) |
|---|---|---|---|
| "模型" | 60 | 100/60 ≈ 1.67 | ln(1.67) ≈ 0.51 |
| "蒸馏" | 3 | 100/3 ≈ 33.3 | ln(33.3) ≈ 3.51 |
"蒸馏"的 IDF 远高于"模型",说明它区分度更强。
五、为什么要套一个 ln(自然对数)?
先理解对数
对数是指数的逆运算。
你知道 ,反过来问"2 的几次方等于 8",答案是 3,写作 。
自然对数 ln 的底数是数学常数 ,问的是"e 的几次方等于 x":
| 式子 | 结果 |
|---|---|
| 0 | |
| 1 | |
| ≈ 4.6 |
为什么要压缩数值?
不加 ln,极端情况会出问题。
假设语料库有 100 万篇文章,某个生僻词只出现在 1 篇:
这个词的 IDF 直接变成 100 万,哪怕它只出现 1 次,得分也会碾压所有其他正常关键词,排名全乱。
加上 ln 之后:,回到正常量级。
更本质的原因:稀有度的边际价值递减
一个词从"10 篇有"变成"1 篇有",稀有度提升了 10 倍,但它的区分能力并不会真的强 10 倍——只是强了一些。
ln 恰好符合这个直觉:
| N/DF | 不用 ln | 用 ln |
|---|---|---|
| 10 | 10 | 2.3 |
| 100 | 100 | 4.6 |
| 1000 | 1000 | 6.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)
余弦相似度公式:
其中 是向量的模(向量的长度),计算方式为:
注意:这里的"模"是向量长度,不是编程里的"取模(求余数)"运算,两者完全不同。
计算结果:
| 对比 | 余弦相似度 | 语义关系 |
|---|---|---|
| A 与 B | ≈ 0.99 | 非常相似 |
| A 与 C | ≈ 0.25 | 差异很大 |
0.99 vs 0.25,清晰地反映了语义距离。
七、TF-IDF 的局限性
最朴素的 TF-IDF 实现有两个缺陷:
- 原始词频线性增长 — 出现 10 次是出现 5 次的两倍,但实际重要性未必如此
- 没有校正文档长度 — 长文章仅仅因为字数多,就容易获得更高得分
这些问题催生了更现代的改进算法,比如 BM25,它在 TF-IDF 的基础上加入了词频饱和与文档长度归一化。
理解 TF-IDF,是读懂检索增强生成(RAG)和搜索引擎原理的第一步。