elasticsearch 评分算法TF-IDF

介绍

在 Lucene 6.0 之前,ES 使用 TF-IDF 作为默认评分算法。

现在主要依赖 BM25 算法(Lucene 6.0+ 及 ES 对应版本默认),同时支持自定义评分逻辑。

TF-IDF(Term Frequency - Inverse Document Frequency,词频-逆文档频率)是一种用于评估关键词在文档集中重要性的统计方法,广泛应用于信息检索(如搜索引擎)、文本挖掘、自然语言处理等领域。其核心思想是:一个词对文档的重要性,与它在该文档中出现的频率成正比,与它在整个文档集中出现的频率成反比。

应用场景

  1. 搜索引擎排序:计算查询词与网页的相关性,TF-IDF 高的网页排名更靠前。
  2. 文本分类/聚类:将文本转换为 TF-IDF 向量,用向量相似度(如余弦距离)判断文本相关性。
  3. 关键词提取:从文档中筛选 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 的核心目的是:

  1. 压缩数值范围,避免因文档集规模导致 IDF 值膨胀;
  2. 体现边际效益递减,符合区分度价值的直觉;
  3. 便于数学运算(累加、比较);
  4. 契合信息论的信息量定义,使公式更具理论合理性。

这也是为什么几乎所有基于 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) = 3
IDF(机器学习) = 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、词向量模型)的基础。


原文出处:/show_1GW26NycS9Vy.html