scikit-learn中TfidfVectorizer计算逻辑及结果复现方案
scikit-learn TfidfVectorizer 计算规则及结果复现方法
核心默认计算逻辑
手动计算结果不一致,核心是没对齐sklearn的默认参数规则,TfidfVectorizer的默认计算流程如下:
- TF(词频)计算:直接取词在当前文档中出现的原始次数,不做除以文档总词数的归一化
- IDF(逆文档频率)计算:默认开启
smooth_idf=True,公式为:
末尾加1的作用是避免完全没有区分度的词权重直接归零IDF(t) = ln( (总文档数 + 1) / (包含词t的文档数 + 1) ) + 1 - 原始TF-IDF值计算:
TF(t,d) * IDF(t),t为目标词,d为目标文档 - 最终归一化:默认使用
norm='l2',将单文档所有词的原始TF-IDF值组成的向量做L2归一化,即每个值除以向量的L2范数(所有值平方和的平方根)
你的场景结果复现
你给出的示例总文档数N=2,我们逐步骤计算:
第一步:计算所有词的IDF
- 词
includ仅在文档1出现,包含它的文档数df=1:IDF(includ) = ln((2+1)/(1+1)) + 1 ≈ 0.405465 + 1 = 1.405465 - 词
name/function/type/argument在两个文档都出现,df=2:IDF(公共词) = ln((2+1)/(2+1)) +1 = 0 +1 = 1
第二步:计算文档1的最终得分
文档1各词原始TF都是1,原始TF-IDF向量为:[1.405465, 1, 1, 1, 1]
- 计算向量L2范数:
sqrt(1.405465² + 1²*4) ≈ sqrt(5.9753) ≈ 2.4444 - L2归一化后得分:
- includ:
1.405465 / 2.4444 ≈ 0.630099,和库输出完全一致 - 四个公共词:
1 / 2.4444 ≈ 0.448320,和库输出完全一致
- includ:
第三步:参数对齐方式
如果文档2的公共词得分和推导结果有差异,可显式指定默认参数避免版本或环境带来的参数变动,即可完全对齐库输出:
tfidf = TfidfVectorizer( tokenizer=processData, stop_words='english', smooth_idf=True, norm='l2', use_idf=True )
常见手动计算错误点
- 使用了其他教程里的IDF公式,漏掉了末尾加的1,或者平滑参数设置和sklearn不同
- 提前对TF做了除以文档总词数的归一化,和sklearn默认的原始词频逻辑不符
- 计算完TF-IDF后未做L2归一化,或者使用了L1归一化
内容的提问来源于stack exchange,提问作者Diyar T Alzuhairi
相关产品推荐
相关产品推荐

