提交3-2-1文本数据处理导论

This commit is contained in:
2026-04-20 20:33:56 +08:00
commit 19e19185f1

556
README.md Normal file
View File

@@ -0,0 +1,556 @@
# 📚 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 向量化示例:从"词"到"数"
### 简单例子:把词变成向量
假设我们只有一个很小的词汇表:
```python
vocab = ["猫", "狗", "鱼", "苹果", "香蕉"]
# "猫" → [1, 0, 0, 0, 0] # 猫在这个词表中的位置
# "狗" → [0, 1, 0, 0, 0] # 狗在这个词表中的位置
# "苹果" → [0, 0, 0, 1, 0] # 苹果在这个词表中的位置
```
**问题**:这只是"位置编码",没有语义信息!
### 更智能的例子:考虑语义
```python
# 理想情况:
# "猫" → [0.9, 0.1, 0.2] # 语义:动物、毛茸茸、会喵喵叫
# "狗" → [0.8, 0.3, 0.1] # 语义:动物、毛茸茸、会汪汪叫
# "苹果" → [0.1, 0.2, 0.9] # 语义:水果、甜的、红色/绿色
# 这样"猫"和"狗"的向量更接近(都是动物)
# "猫"和"苹果"的向量更远(一个是动物,一个是水果)
```
## 2.3 相似度计算:向量的威力
**核心应用:文本相似度**
```python
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, 是, 编程, 语言]
```
**向量化:**
```python
# 统计每个词出现的次数
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 植物)
```
### 词嵌入的实际表示
```python
# 实际中,词向量通常是 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如何得到词向量
```
训练方式1CBOW
・上下文:[猫 __ 鱼] → 预测中间词"吃"
・学习目标:调整向量使得能正确预测
训练方式2Skip-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|×|B|) | 向量相似程度 |
---
# 📝 预习任务
在下一节课之前,请思考以下问题:
## 问题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工具安装
```bash
# 请在命令行安装以下工具
pip install jieba scikit-learn numpy matplotlib
# 验证安装成功
python -c "import jieba; import sklearn; print('安装成功!')"
```
---
# 🚀 下节预告
下一节我们将进入 **3-2-2分词与文本清洗**
学习:
- 如何用 jieba 进行中文分词
- 停用词的作用与过滤方法
- 代码实战:清洗豆瓣评论数据
---
> 🎯 **记住:文本向量化的核心目标是把"符号"变成"可计算的数值向量"**