03 文本向量化:词袋模型与 TF-IDF

03 文本向量化:词袋模型与 TF-IDF

系列文章目录


前言

上一篇文章我们把文本清洗成了干净的词语序列,但计算机不认识"词",只认识"数字"。所以接下来要解决一个核心问题:

如何把一段文本变成一个机器可以计算的向量?

这个把文本转成数值向量的过程,就叫文本向量化(Text Vectorization),也叫文本表示(Text Representation)。它是连接"文本世界"和"数字世界"的桥梁,是整个 NLP 的基础设施。

这篇文章我们聚焦两种最经典、也是最常用的向量化方法:词袋模型(Bag of Words, BoW)TF-IDF


1. 为什么需要文本向量化

先想一个问题:我们要判断"这部电影太棒了"是好评还是差评。计算机怎么做?

  • 计算机不能直接处理"电影""太棒了"这些汉字

  • 但如果我们把每个词映射成一个数字或向量,就能用数学工具(距离、相似度、分类器)来处理了

向量化的核心价值在于:把非结构化的文本,转化为结构化、可计算的数值形式。


2. 词袋模型(Bag of Words, BoW)

2.1 核心思想

词袋模型的想法非常朴素:

把文本拆成一个个词,统计每个词在文档中出现的次数,形成一个"词 → 次数"的向量。至于词的先后顺序,完全不考虑。

因为忽略了顺序,就像"把词装进一个麻袋"一样,所以叫"词袋"。

2.2 举个栗子

假设有三篇文档:

复制代码
文档1:我喜欢学习自然语言处理
文档2:我喜欢编程
文档3:自然语言处理很有趣

第一步:统计所有文档中出现过的词,构建词表(Vocabulary)

复制代码
词表 = [我, 喜欢, 学习, 自然语言, 处理, 编程, 很, 有趣]

第二步:统计每个文档中各词的词频,得到一个向量:

文档 喜欢 学习 自然语言 处理 编程 有趣
文档1 1 1 1 1 1 0 0 0
文档2 1 1 0 0 0 1 0 0
文档3 0 0 0 1 1 0 1 1

这样,每个文档都变成了一个 8 维的向量,计算机就可以直接处理了。

2.3 用 sklearn 实现

复制代码
from sklearn.feature_extraction.text import CountVectorizer
​
corpus = [
    "我喜欢学习自然语言处理",
    "我喜欢编程",
    "自然语言处理很有趣",
]
​
# 注意:CountVectorizer 默认按空格分词,中文需要自定义 tokenizer(这里简化为字符/词级示意)
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
​
print(vectorizer.get_feature_names_out())  # 词表
print(X.toarray())                          # 词频矩阵

2.4 词袋模型的缺点

词袋模型虽然简单,但有两个致命缺点:

  1. 忽略语义和顺序:"我喜欢你"和"你喜欢我"会得到完全一样的向量,但意思相反

  2. 高频词权重过高:一篇文档里"的、了"出现 100 次,"NLP"出现 1 次,向量几乎被虚词主导

  3. 高维稀疏:词表可能有几万词,但每个文档只用到其中一小部分,向量大部分是 0

为了缓解第 2 个缺点,就有了 TF-IDF。


3. TF-IDF

3.1 核心思想

TF-IDF 的核心想法是:

一个词对文档的重要性,不仅取决于它在当前文档中出现得多不多(TF),还取决于它在整个语料中稀不稀罕(IDF)。

如果一个词在很多文档里都出现(比如"的"),那它对区分文档没什么帮助,权重应该降低;如果一个词只在少数文档里出现(比如"深度学习"),那它很可能承载了关键信息,权重应该提高。

3.2 公式

TF-IDF 由两部分相乘:

复制代码
TF-IDF = TF × IDF
  • TF(词频,Term Frequency):词在文档中出现的次数 / 文档总词数
复制代码
TF(t, d) = 词 t 在文档 d 中出现的次数 / 文档 d 的总词数
  • IDF(逆文档频率,Inverse Document Frequency):衡量词的稀有程度
复制代码
IDF(t) = log( 总文档数 N / (包含词 t 的文档数 + 1) )

分母加 1 是为了防止除零(避免某个词在所有文档中都没出现过的情况)。

3.3 直觉理解

  • 如果"深度学习"在 1000 篇文档中只出现在 10 篇里,它的 IDF 很高 → 权重高

  • 如果"的"在 1000 篇文档中出现在 999 篇里,它的 IDF 接近 log(1) = 0 → 权重低

所以 TF-IDF 能自动识别并压低"的、了、是"这类高频无意义词,同时突出真正有区分度的关键词。

3.4 用 sklearn 实现

复制代码
from sklearn.feature_extraction.text import TfidfVectorizer
​
corpus = [
    "我喜欢学习自然语言处理",
    "我喜欢编程",
    "自然语言处理很有趣",
]
​
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
​
print(X.toarray())  # 每个文档的 TF-IDF 向量
print(vectorizer.idf_)  # 每个词的 IDF 值

4. BoW 与 TF-IDF 对比

对比维度 词袋模型 BoW TF-IDF
核心思想 统计词频 词频 × 稀有度
能否区分高频虚词 不能,虚词权重很高 能,自动压低虚词权重
是否体现语义 否(仍是词袋,无顺序)
计算复杂度 略高
适用场景 简单的基线模型 文本分类、关键词提取、检索
是否稀疏 高维稀疏 高维稀疏

💡 小贴士:在实际项目中,TF-IDF 通常是比 BoW 更好的默认选择,尤其在做文本分类和关键词提取时。


5. 常见问题与建议

  1. 中文需要先分词:词袋/TF-IDF 基于"词"统计,中文必须先分词(见第 2 篇)

  2. 词表爆炸问题 :语料规模大时词表可达几十万维,可设置 max_features 限制维度

  3. 丢失顺序信息:如果任务对语序敏感(如判断"猫咬狗"和"狗咬猫"的区别),需要更高级的表示

  4. 适用场景:词袋/TF-IDF 更适合"理解性"任务(分类、聚类、检索),对"生成性"任务力不从心


总结

这一篇我们掌握了两种最基础的文本向量化方法:

  • 词袋模型(BoW):统计词频,简单直观,但忽略顺序和语义、虚词权重过高

  • TF-IDF:在词频基础上加入稀有度惩罚,自动突出关键词,是更实用的改进版

但无论是 BoW 还是 TF-IDF,都有一个共同的局限:它们都是"稀疏的、离散的"表示,无法捕捉词语之间的语义相似度。"苹果"和"香蕉"在向量空间里距离为 0(因为它们从不同时出现)。

要解决这个问题,我们需要一种能表示语义的稠密向量 ------这就是下一篇的主角 Word2Vec

📌 下篇预告04 词向量 Word2Vec:让词变成向量


参考资料

相关推荐
大模型任我行1 小时前
蚂蚁:金融文档解析新范式
人工智能·语言模型·自然语言处理·金融·论文笔记
小白说大模型3 小时前
基于 Qwen3.8-Max 构建 AI 合同精审系统:文档解析、多轮条款分析 Pipeline 工程实战
数据库·人工智能·spring·机器学习·自然语言处理
Asa121383 小时前
Science Advances|大语言模型增强宏基因组酶功能注释
人工智能·语言模型·自然语言处理
傲笑风16 小时前
【openvino】tinybert基于openvino服务化部署(四)
人工智能·python·自然语言处理·nlp·bert·openvino
啊阿狸不会拉杆20 小时前
《自然语言处理:基于大语言模型的方法》第1章 绪论 读书笔记
人工智能·自然语言处理·nlp·easyui·智能体
xierui12312321 小时前
NotionAgent 新增建议修改:如何用Patch、Diff 与人工确认设计 AI 改稿工作流
人工智能·ai·自然语言处理
LadiesAndGentlemen1 天前
环球GeoAI-遥感VLM|2026-08-31|More with Less:通用 VLM 不换架构,也能在遥感基准上打平专用模型
人工智能·神经网络·目标检测·自然语言处理·aigc
小道士写程序1 天前
自然语言处理NLP - 开篇 什么是 NLP
人工智能·自然语言处理
A55566677787891 天前
金融级安全的OpenClaw平替方案商,支持内网隔离与源码级定制交付2026
人工智能·安全·自然语言处理·金融