d12728331d1c289536950a0cba646cfff0d7228d
📚 3-2-1 文本数据处理导论
🎯 本章学习目标
| 目标 | 内容 |
|---|---|
| 理解 | 为什么文本不能直接用于计算机计算 |
| 掌握 | 文本向量化的核心思想与数学原理 |
| 了解 | 从 BoW → TF-IDF → Embedding 的演进逻辑 |
| 认识 | 文本处理的完整流程框架 |
📖 第一部分:为什么文本处理这么难?
1.1 计算机的"语言障碍"
计算机擅长什么?
数字计算: 1 + 2 = 3 ✅
图像处理: 像素矩阵运算 ✅
逻辑判断: if A > B then ... ✅
计算机不擅长什么?
文本理解:
"今天天气真好!" → ??? → 计算机无法直接"理解"
"Python是世界上最好的语言" → ??? → 计算机不知道这是什么意思
核心问题:
计算机只能处理数字,文本是符号,符号不能直接用于计算。
1.2 文本 vs 图像:本质区别
┌─────────────────────────────────────────────────────────┐
│ 图像数据 │
├─────────────────────────────────────────────────────────┤
│ 📐 空间结构化数据 │
│ ・像素 = 数字(0-255) │
│ ・位置关系 = 空间关系(上下左右) │
│ ・相邻像素通常相关 │
│ ・直接可以用矩阵表示 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 文本数据 │
├─────────────────────────────────────────────────────────┤
│ 📝 序列符号化数据 │
│ ・词语/字符 = 离散符号 │
│ ・位置关系 = 逻辑顺序(不是物理位置) │
│ ・符号本身无"数值含义" │
│ ・无法直接用数字运算 │
└─────────────────────────────────────────────────────────┘
1.3 文本处理的核心挑战
挑战1:符号到数字的转换
"Python" → ??? → [?, ?, ?, ...]
挑战2:一词多义
"苹果" 可以指:
・一种水果(营养丰富)
・一家公司(Apple Inc.)
・手机品牌(苹果手机)
挑战3:词序敏感
"我爱你" vs "你爱我"
・词语完全相同
・顺序不同
・意思完全相反
挑战4:同义表达
"电脑" vs "计算机" vs "计算机器"
・不同符号
・相同含义
📖 第二部分:文本向量化的核心思想
2.1 核心目标:把所有文本变成"向量"
文本(符号) → 数值向量 → 计算机可以计算 → AI模型处理
为什么必须是向量?
因为计算机擅长:
・向量加减:v1 + v2 = ?
・向量点积:v1 · v2 = ?
・向量距离:||v1 - v2|| = ?
・矩阵运算:A × B = ?
但计算机不擅长:
・字符串比较:"Python" == "Java" ?
・词语推理:"猫" 类似于 "狗" ?
2.2 向量化示例:从"词"到"数"
简单例子:把词变成向量
假设我们只有一个很小的词汇表:
vocab = ["猫", "狗", "鱼", "苹果", "香蕉"]
# "猫" → [1, 0, 0, 0, 0] # 猫在这个词表中的位置
# "狗" → [0, 1, 0, 0, 0] # 狗在这个词表中的位置
# "苹果" → [0, 0, 0, 1, 0] # 苹果在这个词表中的位置
问题:这只是"位置编码",没有语义信息!
更智能的例子:考虑语义
# 理想情况:
# "猫" → [0.9, 0.1, 0.2] # 语义:动物、毛茸茸、会喵喵叫
# "狗" → [0.8, 0.3, 0.1] # 语义:动物、毛茸茸、会汪汪叫
# "苹果" → [0.1, 0.2, 0.9] # 语义:水果、甜的、红色/绿色
# 这样"猫"和"狗"的向量更接近(都是动物)
# "猫"和"苹果"的向量更远(一个是动物,一个是水果)
2.3 相似度计算:向量的威力
核心应用:文本相似度
import numpy as np
def cosine_similarity(v1, v2):
"""计算两个向量的余弦相似度"""
return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
# 假设这些是词的向量表示
cat = np.array([0.9, 0.1, 0.2]) # 猫
dog = np.array([0.8, 0.3, 0.1]) # 狗
apple = np.array([0.1, 0.2, 0.9]) # 苹果
print("猫 vs 狗:", cosine_similarity(cat, dog)) # 应该较高(都是动物)
print("猫 vs 苹果:", cosine_similarity(cat, apple)) # 应该较低(动物 vs 水果)
输出结果:
猫 vs 狗: 0.862
猫 vs 苹果: 0.149
结论:
- 相似度 0.862 → "猫"和"狗"语义相近 ✅
- 相似度 0.149 → "猫"和"苹果"语义相差很远 ✅
🎯 这就是文本向量化的威力:把"语义"变成"可计算的数值"!
📖 第三部分:从 BoW 到 Embedding:演进之路
3.1 演进概览
文本向量化的三种主要方法:
[BoW] ───→ [TF-IDF] ───→ [Word Embedding]
(词袋模型) (词频权重) (词向量嵌入)
简单粗暴 加入词重要性 蕴含语义信息
无语义 部分语义 深度语义
3.2 BoW(词袋模型)—— 最简单的方法
原理
把文本看成"一袋词",不考虑顺序,只管词出现了几次。
文本1: "Python 是 编程 语言"
文本2: "Java 是 编程 语言"
词表: [Python, Java, 是, 编程, 语言]
向量化:
# 统计每个词出现的次数
text1_vec = [1, 0, 1, 1, 1] # Python=1, Java=0, 是=1, 编程=1, 语言=1
text2_vec = [0, 1, 1, 1, 1] # Python=0, Java=1, 是=1, 编程=1, 语言=1
优缺点
| 优点 | 缺点 |
|---|---|
| 简单直观 | 忽略词序 |
| 容易实现 | "我爱你"和"你爱我"向量完全相同 |
| 计算速度快 | 所有词同等重要 |
3.3 TF-IDF —— 加入词的重要性
原理
BoW 的问题是:所有词同等重要。 "Python"和"的"在 BoW 中权重相同,这不合理。
TF-IDF = 词频(TF) × 逆文档频率(IDF)
TF = 这个词在本文中出现了多少次
IDF = 这个词在所有文档中多不多(越多越不重要)
TF-IDF = TF × IDF
为什么有效?
・"Python":在少数文档中高频出现 → TF高, IDF高 → TF-IDF高 ✅ 重要词
・"的":在所有文档中都出现 → TF高, IDF低 → TF-IDF低 ❌ 停用词
直观理解
TF-IDF = 词的重要性 × 词的独特性
・高频出现 ≠ 重要("的"在所有文章都出现)
・罕见词 ≠ 不重要("TensorFlow"只在AI文章出现)
・既高频又独特 = 真正重要的词
3.4 Word Embedding(词嵌入)—— 蕴含语义
BoW 和 TF-IDF 的根本问题
"猫" → [1, 0, 0, ...] # 只是"位置编码"
"狗" → [0, 1, 0, ...] # 猫和狗的位置不同
"小猫" → [0, 0, 1, ...] # 但它们语义相近,向量却正交!
问题:BoW 和 TF-IDF 无法表达语义相似性!
Embedding 的思想
不再用"位置"表示词,而是用"语义空间"表示词
语义空间中的位置:
↑
动物 植物
| ↑ 猫 ↑ 狗 ↑ 苹果
| ↗ ↗ ↑
| ↗ ↗ ↑
| ↗ ↗ ← 语义相近的词距离近 →
|──────────→────────────────────────────→
0 抽象 具体
| ↑
| ↑
| ↑ 人
|
└────────────────────────────────────→
"猫"和"狗"距离近(都是动物)
"猫"和"苹果"距离远(动物 vs 植物)
词嵌入的实际表示
# 实际中,词向量通常是 50/100/300 维
# 这里用 3 维举例
cat = [0.9, 0.1, 0.2] # 猫:动物属性高,植物属性低
dog = [0.8, 0.3, 0.1] # 狗:动物属性高
apple = [0.1, 0.2, 0.9] # 苹果:植物属性高
# 计算相似度
cosine_similarity(cat, dog) # ≈ 0.97 → 非常相似
cosine_similarity(cat, apple) # ≈ 0.15 → 很不相似
Word2Vec:如何得到词向量?
训练方式1:CBOW
・上下文:[猫 __ 鱼] → 预测中间词"吃"
・学习目标:调整向量使得能正确预测
训练方式2:Skip-gram
・中心词:[吃] → 预测上下文[猫, 鱼]
・学习目标:调整向量使得能正确预测
原理:"相似上下文中的词,语义相似"
・猫和狗经常出现在相似的上下文中("猫吃鱼"、"狗吃肉")
・所以它们的向量也会相似
📖 第四部分:文本处理的完整流程
4.1 流程图
┌──────────────────────────────────────────────────────────────────┐
│ 文本数据 │
│ "今天天气真不错!" │
└─────────────────────────┬────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 1. 文本预处理 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 分词 │→ │ 去停用词│→ │ 统一大小│→ │ 去除标点│ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ "今天/天气/真/不错" → "今天/天气/不错" │
└─────────────────────────┬────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 2. 文本向量化 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ BoW │ │ TF-IDF │ │ Embedding│ │ 预训练模型│ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ ↓ ↓ ↓ ↓ │
│ [1,0,2,0,1] [0.5,0,0.8] [0.9,0.3] [BERT向量] │
└─────────────────────────┬────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 3. 下游任务 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 分类 │ │ 相似度 │ │ 聚类 │ │ 生成 │ │
│ │ 情感分析│ │ 文本匹配│ │ 主题分组│ │ 聊天机器人│ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└──────────────────────────────────────────────────────────────────┘
4.2 各环节详解
环节1:文本预处理
为什么需要预处理?
原始文本:
"今天天气真不错!!Python是一门很棒的语言,PYTHON也很重要!!!"
预处理后:
["今天", "天气", "不错", "Python", "语言"]
预处理步骤:
| 步骤 | 输入 | 输出 | 作用 |
|---|---|---|---|
| 分词 | "今天天气不错" | ["今天", "天气", "不错"] | 把文本切成词 |
| 去停用词 | ["今天", "天气", "不错"] | ["天气", "不错"] | 去掉无意义词 |
| 统一大小写 | ["Python", "python"] | ["python", "python"] | 归一化 |
| 去标点 | ["语言!!!"] | ["语言"] | 清理噪音 |
环节2:文本向量化
选择向量化方法的原则:
| 方法 | 适用场景 | 不适用场景 |
|---|---|---|
| BoW | 基线模型、快速原型 | 需要语义理解 |
| TF-IDF | 文本分类、关键词提取 | 同义词识别 |
| Embedding | 语义相似度、推荐系统 | 需要精确匹配 |
| 预训练模型 | 通用NLP任务 | 计算资源有限 |
环节3:下游任务
分类任务:
"这部电影太好看了!" → [正面, 0.95] → 正面情感 ✅
相似度任务:
"如何学习Python?" → 找到相似的:"Python入门教程" ✅
生成任务:
"今天天气" → 续写:"今天天气真好,适合出去玩" ✅
📖 第五部分:工具生态概览
5.1 Python NLP 工具箱
┌─────────────────────────────────────────────────────────┐
│ 中文分词工具 │
├─────────────────────────────────────────────────────────┤
│ jieba(结巴) ・最流行的中文分词库 │
│ ・支持精确/全/搜索引擎模式 │
│ ・pip install jieba │
├─────────────────────────────────────────────────────────┤
│ HanLP ・功能强大,支持词性标注、命名实体识别 │
│ SnowNLP ・简单好用,专注文本处理 │
│ LTP ・哈工大出品,准确率高 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 英文NLP工具 │
├─────────────────────────────────────────────────────────┤
│ NLTK ・经典NLP库,教学首选 │
│ spaCy ・速度快,工业级 │
│ Stanford NLP ・学术标准,准确性高 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 文本向量化工具 │
├─────────────────────────────────────────────────────────┤
│ scikit-learn ・BoW、TF-IDF 实现 │
│ Gensim ・Word2Vec、Doc2Vec │
│ TensorFlow/PyTorch ・深度学习文本处理 │
│ transformers ・BERT、GPT 等预训练模型 │
└─────────────────────────────────────────────────────────┘
5.2 本课程使用的工具
| 工具 | 用途 | 安装命令 |
|---|---|---|
| jieba | 中文分词 | pip install jieba |
| sklearn | TF-IDF、向量化 | pip install scikit-learn |
| numpy | 数值计算 | pip install numpy |
| matplotlib | 可视化 | pip install matplotlib |
📖 第六部分:本章知识地图
6.1 核心概念
文本数据处理
│
├── 核心问题:文本(符号) → 向量(数字)
│
├── 向量化方法
│ ├── BoW(词袋模型)
│ │ └── 核心:统计词频,忽略顺序
│ │
│ ├── TF-IDF(词频-逆文档频率)
│ │ └── 核心:词的重要性 × 词的独特性
│ │
│ └── Word Embedding(词嵌入)
│ └── 核心:用语义空间表示词
│
└── 处理流程
├── 文本预处理(分词、去停用词)
├── 向量化
└── 下游任务(分类、相似度、生成)
6.2 数学公式速查
| 方法 | 公式 | 含义 |
|---|---|---|
| TF | TF(t) = 词t在文档中出现次数 | 词在本文中多不多 |
| IDF | IDF(t) = log(总文档数 / 含词t的文档数) | 词是否罕见 |
| TF-IDF | TF-IDF(t) = TF(t) × IDF(t) | 词的重要程度 |
| 余弦相似度 | cos(θ) = (A·B) / ( | A |
📝 预习任务
在下一节课之前,请思考以下问题:
问题1:分词挑战
英文分词很简单(空格分隔):
"I love Python" → ["I", "love", "Python"]
但中文分词很难:
"我爱你中国" 可以切成:
["我", "爱", "你", "中国"] ?
["我爱你", "中国"] ?
["我爱", "你中国"] ?
请思考:为什么中文分词比英文难?
问题2:向量化思考
假设我们有3个文档:
Doc1: "Python是编程语言"
Doc2: "Java是编程语言"
Doc3: "猫是动物"
用BoW模型,词表是:[Python, Java, 是, 编程, 语言, 猫, 动物]
问题:
1. Doc1 和 Doc2 的相似度是多少?为什么?
2. Doc1 和 Doc3 的相似度是多少?为什么?
3. 这个结果合理吗?为什么?
问题3:工具安装
# 请在命令行安装以下工具
pip install jieba scikit-learn numpy matplotlib
# 验证安装成功
python -c "import jieba; import sklearn; print('安装成功!')"
🚀 下节预告
下一节我们将进入 3-2-2:分词与文本清洗, 学习:
- 如何用 jieba 进行中文分词
- 停用词的作用与过滤方法
- 代码实战:清洗豆瓣评论数据
🎯 记住:文本向量化的核心目标是把"符号"变成"可计算的数值向量"!
Description
Languages
Python
100%