介绍
在 Lucene 6.0 之前,ES 使用 TF-IDF 作为默认评分算法。
现在主要依赖 BM25 算法(Lucene 6.0+ 及 ES 对应版本默认),同时支持自定义评分逻辑。
TF-IDF(Term Frequency - Inverse Document Frequency,词频-逆文档频率)是一种用于评估关键词在文档集中重要性的统计方法,广泛应用于信息检索(如搜索引擎)、文本挖掘、自然语言处理等领域。其核心思想是:一个词对文档的重要性,与它在该文档中出现的频率成正比,与它在整个文档集中出现的频率成反比。
应用场景
- 搜索引擎排序:计算查询词与网页的相关性,TF-IDF 高的网页排名更靠前。
- 文本分类/聚类:将文本转换为 TF-IDF 向量,用向量相似度(如余弦距离)判断文本相关性。
- 关键词提取:从文档中筛选 TF-IDF 权重高的词作为核心关键词(如论文摘要的关键词提取)。
TF-IDF 公式
TF-IDF 由两部分组成:词频(TF) 和逆文档频率(IDF),最终通过两者的乘积计算关键词的权重。
定义:关键词 t 在文档 d 中的最终权重,为 TF 和 IDF 的乘积。
公式:
TF-IDF(t, d) = TF(t, d) × IDF(t)
含义:
- 若一个词在某文档中频繁出现(高 TF),且在整个文档集中很少出现(高 IDF),则其 TF-IDF 权重高,说明该词对该文档的主题有很强的代表性。
TF(t, d) 解释
词频(TF,Term Frequency)
定义:某个关键词 t 在当前文档 d 中出现的频率。
作用:衡量关键词在单篇文档中的“重要性”——出现次数越多,可能越能代表文档主题(但需结合 IDF 修正)。
计算公式:
TF(t, d) = 关键词 t 在文档 d 中出现的次数 / 文档 d 中所有词的总次数
(也可简化为“出现次数”,无需除以总次数,具体视场景而定)
示例:
文档 d 内容:"猫是一种可爱的动物,猫喜欢吃鱼"
- 总词数:7(“猫”“是”“一种”“可爱的”“动物”“喜欢”“吃鱼”)
- “猫”出现次数:2 →
TF(猫, d) = 2/7 ≈ 0.286
IDF(t)解释
逆文档频率(IDF,Inverse Document Frequency)
定义:衡量关键词 t 在整个文档集(或语料库)中的“稀有度”。
作用:抑制常见词(如“的”“是”等停用词)的权重,突出稀有词的重要性——一个词在越少的文档中出现,其区分不同文档的能力越强。
计算公式:
IDF(t) = log( N / ( df(t) + 1) )
N:文档集中所有文档的总数。df(t)(Document Frequency):包含关键词t的文档数量。- 分母加 1 是为了避免
df(t)=0时(即没有文档包含t)出现除以 0 的错误(此时IDF(t) = log(N/1) = logN)。
注意:如果所有的文档都包含该关键词,那么对数结果是 负数,可以将公式优化,如:log((N+1)/(df(t)+1)))
为什么使用对数(log)
在 IDF(逆文档频率)的计算公式中,引入对数(log)主要是为了平衡词的区分度对权重的影响,避免因文档集规模过大导致 IDF 值膨胀,同时让 IDF 符合“边际效益递减”的直观逻辑。具体原因如下:
1. 抑制 IDF 值的增长幅度,避免数值过大
IDF 的核心逻辑是:一个词在越少的文档中出现(即 df(t) 越小),其区分度越高,权重应越大。
原始未加 log 的逻辑可表示为:IDF(t) ∝ N / df(t)(N 是总文档数,df(t) 是含词 t 的文档数)
但这个比例关系存在问题:当 N 很大(如百万级文档)且 df(t) 很小时(如 1),N/df(t) 会非常大(如 100 万),导致 IDF 值过大,在后续计算(如 TF-IDF 乘积)中会过度放大该词的权重,掩盖其他词的影响。
而对数函数(如自然对数 ln 或常用对数 log10)是单调递增但增长速率逐渐放缓的函数,能有效“压缩”大数值的范围。例如:
- 当
N/df(t) = 10时,log(10) ≈ 2.3(自然对数) - 当
N/df(t) = 100时,log(100) ≈ 4.6(仅为前者的 2 倍,而非 10 倍) - 当
N/df(t) = 1000时,log(1000) ≈ 6.9(增长幅度进一步缩小)
通过 log 转换,IDF 值的增长会随 N/df(t) 的增大而逐渐平缓,避免了数值膨胀对整体权重的过度影响。
2. 符合“区分度边际效益递减”的直觉
从语义上看,一个词的区分度提升带来的“价值”是边际递减的:
- 从“在 1000 篇文档中出现”到“在 100 篇文档中出现”,区分度提升显著,IDF 应明显增大;
- 从“在 10 篇文档中出现”到“在 1 篇文档中出现”,区分度提升同样显著,但幅度不应比前者大 10 倍(实际仅差一个数量级)。
对数函数恰好能体现这种特性:log(N/df(t)) 的差值随 df(t) 减小而增大,但增速放缓,符合人类对“区分度价值”的直觉判断。
3. 数学上便于累加和比较
在信息检索中,文档与查询的相关性通常是多个词的 IDF 加权和(如 TF-IDF 总和)。对数函数的一个重要性质是:log(a) + log(b) = log(a×b)
这使得多词的 IDF 组合可以转换为对数内的乘积运算,在数学上更便于处理和优化。同时,log 转换后的值域更集中(通常在 0~10 之间,取决于文档集规模),方便不同词的 IDF 进行比较和加权。
4. 与信息论中的“信息量”概念一致
在信息论中,一个事件的“信息量”(自信息)定义为 -log(P(x)),其中 P(x) 是事件发生的概率。概率越小的事件(如稀有词出现),信息量越大。
IDF 的本质是衡量一个词的“稀有度带来的信息量”,df(t)/N 可视为“随机选一篇文档包含词 t”的概率,因此:IDF(t) = log(N/df(t)) = log(1/(df(t)/N)) = -log(df(t)/N)
这与信息论中“稀有事件信息量更大”的定义完全一致,使 IDF 具备了坚实的理论基础。
总结
IDF 中使用 log 的核心目的是:
- 压缩数值范围,避免因文档集规模导致 IDF 值膨胀;
- 体现边际效益递减,符合区分度价值的直觉;
- 便于数学运算(累加、比较);
- 契合信息论的信息量定义,使公式更具理论合理性。
这也是为什么几乎所有基于 IDF 的算法(如 TF-IDF、BM25)都会采用对数转换的原因。
示例
假设文档集有 1000 篇文档(N=1000):
- 关键词“猫”出现在 10 篇文档中(
df(t)=10)→IDF(猫) = log(1000/(10+1)) ≈ log(90.9) ≈ 1.96 - 关键词“的”出现在 900 篇文档中(
df(t)=900)→IDF(的) = log(1000/(900+1)) ≈ log(1.11) ≈ 0.045
可见,“猫”的 IDF 远高于“的”,说明“猫”是更有区分度的关键词。
TF-IDF 的计算示例
假设文档集有 3 篇文档(N=3):
- 文档 1:
"机器学习是人工智能的一个分支,机器学习的核心是算法" - 文档 2:
"人工智能包含机器学习、深度学习等分支,人工智能正在快速发展" - 文档 3:
"深度学习是机器学习的一个子领域,深度学习依赖大数据"
步骤 1:分词并计算 TF
以关键词“机器学习”为例:
- 文档 1 中“机器学习”出现 2 次,总词数 10 →
TF(机器学习, 文档1) = 2/10 = 0.2 - 文档 2 中“机器学习”出现 1 次,总词数 11 →
TF(机器学习, 文档2) = 1/11 ≈ 0.09 - 文档 3 中“机器学习”出现 1 次,总词数 9 →
TF(机器学习, 文档3) = 1/9 ≈ 0.11
步骤 2:计算 IDF
“机器学习”出现在文档 1、2、3 中 → df(t) = 3IDF(机器学习) = log(3/(3+1)) = log(0.75) ≈ -0.125(注:此处为简化计算,实际中可能用自然对数或调整公式避免负数,如 log((N+1)/(df(t)+1)))
步骤 3:计算 TF-IDF 权重
- 文档 1:
0.2 × (-0.125) ≈ -0.025(示例中因 IDF 为负,实际场景会优化公式避免负权重) - 文档 2:
0.09 × (-0.125) ≈ -0.011 - 文档 3:
0.11 × (-0.125) ≈ -0.014
优缺点
优点
- 简单直观,计算效率高,适合大规模文本处理。
- 能有效抑制常见词,突出稀有词的重要性。
缺点:
缺陷:TF 随词频无限增长(例如,词频 100 的得分是词频 1 的 100 倍),容易导致“关键词堆砌”的文档排名过高,因此被 BM25 替代。
- 忽略词的语义和上下文:例如“苹果(水果)”和“苹果(公司)”被视为同一词,无法区分歧义。
- 对文档长度敏感:长文档可能包含更多关键词,导致 TF 偏高。
- 未考虑词的位置:标题中的词与正文中的词权重相同,而实际标题更重要。
改进与扩展
为弥补 TF-IDF 的不足,实际应用中常结合以下优化:
- 词频修正:用
log(1 + TF)替代原始 TF,避免词频过高导致权重膨胀(如 Lucene 早期做法)。 - 加入停用词表:预先过滤“的”“是”等无意义词,减少计算量。
- 结合词向量(Word2Vec、BERT 等):通过语义向量弥补 TF-IDF 语义缺失的问题。
总结
TF-IDF 是一种经典的文本特征提取方法,核心通过“词频”和“逆文档频率”的平衡,量化关键词对文档的重要性。尽管存在语义不足等缺陷,但其简单高效的特性使其至今仍被广泛应用,也是理解更复杂文本处理算法(如 BM25、词向量模型)的基础。