557 lines
20 KiB
Markdown
557 lines
20 KiB
Markdown
# 📚 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:如何得到词向量?
|
||
|
||
```
|
||
训练方式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|×|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 进行中文分词
|
||
- 停用词的作用与过滤方法
|
||
- 代码实战:清洗豆瓣评论数据
|
||
|
||
---
|
||
|
||
> 🎯 **记住:文本向量化的核心目标是把"符号"变成"可计算的数值向量"!**
|