📚 3-2-1 文本数据处理导论
🎯 本章学习目标
| 目标 | 内容 |
|---|---|
| 理解 | 什么是文本数据,以及计算机如何读取文本 |
| 掌握 | 为什么文本不能直接用于计算机计算 |
| 理解 | 向量、相似度的基本概念(零基础讲解) |
| 掌握 | 文本向量化的核心思想与数学原理 |
| 了解 | 从 BoW → TF-IDF → Embedding 的演进逻辑 |
📖 第一部分:什么是文本数据?
1.1 文本数据的定义
文本数据是由文字、符号组成的序列信息,是人类语言在计算机中的表示形式。
文本数据的例子
一句话:"今天天气真好"
一篇文章:一篇新闻报道
一条评论:"这家餐厅的菜太好吃了!"
一段对话:"你好,请问这本书多少钱?"
一首诗:"床前明月光,疑是地上霜"
文本数据的特征
| 特征 | 说明 | 示例 |
|---|---|---|
| 离散符号 | 由离散的字符/词组成 | "hello" 由 h,e,l,l,o 这5个字符组成 |
| 序列性 | 符号按特定顺序排列 | "我爱你" ≠ "你爱我" |
| 语义丰富 | 同样的词不同场景意思不同 | "苹果"可以是水果或手机品牌 |
| 上下文相关 | 词的意思依赖上下文 | "他打了猫,猫跑了" 中两个"猫"意思相同 |
1.2 计算机如何"读取"文本?
对比:图像 vs 文本
图像数据的读取:
图像文件(.jpg/.png)
↓
计算机读取像素值
↓
存储为3维矩阵 [高度, 宽度, 通道]
↓
一张 1920×1080 的彩色图 = 1920 × 1080 × 3 = 6,220,800 个数字
文本数据的读取:
文本文件(.txt/.md)
↓
计算机读取字符编码(ASCII/UTF-8)
↓
存储为字符序列(每个字符是一个数字编码)
↓
"Python" → [80, 121, 116, 104, 111](ASCII编码)
字符编码:用数字表示字符
计算机并不能直接"认识"字符,它只认识数字。所以需要一种映射规则把字符变成数字:
ASCII编码(英文):
'A' → 65, 'B' → 66, ..., 'Z' → 90
'a' → 97, 'b' → 98, ..., 'z' → 122
'0' → 48, '1' → 49, ..., '9' → 57
UTF-8编码(支持中文):
'中' → 20013, '文' → 25991, 'P' → 80, 'y' → 121
文本的"存储形式"
# 文本在计算机中的存储方式
text = "Hello"
# 如果我们看它的"数字形式":
print([ord(c) for c in text])
# 输出: [72, 101, 108, 108, 111]
# 72='H', 101='e', 108='l', 111='o'
# 中文例子
text_cn = "你好"
print([ord(c) for c in text_cn])
# 输出: [20320, 22909]
# 20320='你', 22909='好'
1.3 计算机擅长什么?不擅长什么?
计算机擅长的任务
✅ 数字计算:1 + 2 = 3
✅ 逻辑判断:if (a > b) then ...
✅ 矩阵运算:图像卷积、矩阵乘法
✅ 精确匹配:字符串完全相同比较
✅ 模式识别:符合规则的数据查找
计算机不擅长的任务
❌ 语义理解:计算机不知道"今天天气真好"是好心情还是讽刺
❌ 情感判断:计算机不知道"真是绝了"是夸人还是骂人
❌ 模糊推理:"大概"、"也许"、"差不多"无法精确处理
❌ 创意创作:写诗、写小说、编笑话
❌ 常识理解:"水往低处流"这种常识计算机不懂
为什么计算机不擅长理解文本?
原因一:文本是"符号",不是"数值"
计算机大脑 = 计算器(专门处理数字)
文本 = 一堆符号(对计算机来说就像乱码)
数字:1, 2, 3, 100.5, -7 → 计算机直接能算
文本:"好"、"bad"、"hello" → 计算机不知道啥意思
原因二:语义不是显式表达的
文本:"他今天心情不太好,因为下雨了"
计算机看到:[他, 今天, 心情, 不, 好, 因为, 下雨, 了]
↓
人类理解:他在不开心,因为外面下雨了(影响心情)
↓
计算机:???不理解下雨和心情的因果关系
原因三:同样的符号,不同的语境,不同的意思
"苹果真好吃"
→ 说的是水果
"苹果手机真贵"
→ 说的是手机品牌
计算机怎么知道?因为有上下文!
但计算机理解上下文的能力很弱
📖 第二部分:向量基础入门(零基础科普)
2.1 什么是向量?
向量的直观理解
向量 = 有方向的量
在日常生活中:
・速度:每小时60公里,向北走
・力:10牛顿,向右推
・风向:东南风,每秒5米
这些都是有"方向"和"大小"的量,就是向量!
向量在数学中的表示
一维向量(数轴上的点):
←———————————|———————————→
-3 -2 -1 0 1 2 3
点A在位置 2 → 向量A = [2]
点B在位置 -3 → 向量B = [-3]
二维向量(平面上的点):
y
↑
|
3 | * A(2,3)
|
2 |
|
1 | * B(4,1)
|
0---+—————————————→ x
0 1 2 3 4 5
向量A = [2, 3] (横坐标2,纵坐标3)
向量B = [4, 1]
三维向量(立体空间):
z
↑ * C(1,2,3)
| /
| /
| /
|/__________→ y
/
/
/_________→ x
(0,0,0)
向量C = [1, 2, 3]
Python中创建向量
import numpy as np
# 一维向量
v1 = np.array([3]) # 只有1个数字
print(f"v1 = {v1}")
# 二维向量
v2 = np.array([2, 3]) # 2个数字,表示平面上的一个点
print(f"v2 = {v2}")
# 三维向量
v3 = np.array([1, 2, 3]) # 3个数字,表示立体空间的一个点
print(f"v3 = {v3}")
# 更多维向量(机器学习中常用)
v100 = np.array([0.1, 0.5, -0.3, 0.8, ...]) # 100维!
print(f"v100有 {len(v100)} 个元素")
2.2 向量的基本运算
加法和减法
import numpy as np
# 向量加法:对应位置相加
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = a + b # [1+4, 2+5, 3+6] = [5, 7, 9]
print(f"a + b = {c}") # [5, 7, 9]
# 直观理解:
# a = [1, 2, 3] 从原点出发走1步、再走2步、再走3步
# b = [4, 5, 6] 从原点出发走4步、再走5步、再走6步
# a + b = 从原点走完a再走b = [5, 7, 9]
数乘(标量乘法)
# 向量乘以一个数字(标量)
v = np.array([1, 2, 3])
result = v * 2 # [1*2, 2*2, 3*2] = [2, 4, 6]
print(f"v * 2 = {result}") # [2, 4, 6]
# 直观理解:
# v = [1, 2, 3] 表示"方向"
# v * 2 = [2, 4, 6] 方向不变,长度变成2倍
向量的长度(模/范数)
# 向量的长度 = 从原点到终点的距离
v = np.array([3, 4])
# 用勾股定理:3² + 4² = 25,√25 = 5
length = np.linalg.norm(v)
print(f"向量 [3, 4] 的长度 = {length}") # 5.0
# 另一个例子
v2 = np.array([1, 1])
length2 = np.linalg.norm(v2)
print(f"向量 [1, 1] 的长度 = {length2:.2f}") # 1.41
2.3 点积(Dot Product)— 最重要的运算
什么是点积?
点积 = 对应位置相乘,再求和
# 两个向量对应位置相乘,然后加起来
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 点积计算过程:
# 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
dot = np.dot(a, b)
print(f"点积 = {dot}") # 32
# 或者用 @ 运算符
print(f"a @ b = {a @ b}") # 32
点积的直观理解
点积 = a的长度 × b的长度 × cos(夹角)
如果 a 和 b 方向相同:夹角 = 0°,cos(0) = 1,点积 = |a|×|b|(最大)
如果 a 和 b 垂直: 夹角 = 90°,cos(90) = 0,点积 = 0(最小)
如果 a 和 b 相反: 夹角 = 180°,cos(180) = -1,点积 = -|a|×|b|(负最大)
2.4 余弦相似度 — 用点积判断"像不像"
什么是相似度?
相似度 = 两个向量有多"像"
相似度高的例子:
・"猫"和"狗":都是动物,都四只脚,都会叫
・"红色"和"黄色":都是颜色,都是暖色调
・"跑步"和"游泳":都是运动
相似度低的例子:
・"猫"和"石头":一个是动物,一个不是
・"热"和"冷":意思相反
・"太阳"和"细菌":几乎没有共同点
余弦相似度公式
A · B
cos(θ) = ──────────
|A| × |B|
・A · B = 向量A和B的点积
・|A| = 向量A的长度
・|B| = 向量B的长度
・cos(θ) = 相似度,范围是 [-1, 1]
余弦相似度的值代表什么?
| cos(θ) 值 | 夹角 θ | 相似程度 | 示例 |
|---|---|---|---|
| 1.0 | 0° | 完全相同 | 同一向量 |
| 0.8~0.99 | 0~37° | 非常相似 | "猫" vs "狗" |
| 0.5~0.8 | 0~60° | 比较相似 | "跑步" vs "运动" |
| 0.3~0.5 | 60~72° | 有些相似 | "苹果" vs "水果" |
| 0 | 90° | 毫不相关 | "猫" vs "石头" |
| -1.0 | 180° | 完全相反 | "高" vs "矮" |
Python计算余弦相似度
import numpy as np
def cosine_similarity(a, b):
"""计算余弦相似度"""
dot = np.dot(a, b) # 点积
norm_a = np.linalg.norm(a) # 向量a的长度
norm_b = np.linalg.norm(b) # 向量b的长度
return dot / (norm_a * norm_b)
# 例子1:方向完全相同的向量
a = np.array([1, 2, 3])
b = np.array([2, 4, 6]) # b是a的两倍,方向完全相同
print(f"相似度 = {cosine_similarity(a, b):.3f}") # 1.000
# 例子2:方向完全相反的向量
a = np.array([1, 2, 3])
b = np.array([-1, -2, -3]) # b是a的相反方向
print(f"相似度 = {cosine_similarity(a, b):.3f}") # -1.000
# 例子3:垂直的向量
a = np.array([1, 0])
b = np.array([0, 1])
print(f"相似度 = {cosine_similarity(a, b):.3f}") # 0.000
# 例子4:日常生活中的"相似"
print("\n=== 语义相似度示例 ===")
# 假设这些是词的"意义向量"(简化版)
# 维度:[是否是动物, 是否有生命, 是否能移动]
cat = np.array([0.9, 0.9, 0.8]) # 猫:动物,有生命,能移动
dog = np.array([0.8, 0.9, 0.8]) # 狗:动物,有生命,能移动
apple = np.array([0.1, 0.3, 0.0]) # 苹果:植物,略有生命,不能移动
print(f"猫 vs 狗: {cosine_similarity(cat, dog):.3f}") # 非常接近1
print(f"猫 vs 苹果: {cosine_similarity(cat, apple):.3f}") # 接近0
📖 第三部分:文本向量化的核心思想
3.1 核心目标:把所有文本变成"向量"
文本(符号) → 数值向量 → 计算机可以计算 → AI模型处理
为什么必须是向量?
因为计算机擅长:
・向量加减:v1 + v2 = ?
・向量点积:v1 · v2 = ?
・向量距离:||v1 - v2|| = ?
・余弦相似度:cos(θ) = ?
但计算机不擅长:
・字符串比较:"Python" == "Java" ?
・词语推理:"猫" 类似于 "狗" ?
文本向量化的意义:
"猫"和"狗"在文本中可能完全不相关
但如果我们知道它们都是"动物",向量就会接近
计算机就能"理解"它们的相似性了!
3.2 向量化示例:从"词"到"数"
简单例子:把词变成向量(位置编码)
# 假设我们有一个很小的词汇表(只有5个词)
vocab = ["猫", "狗", "鱼", "苹果", "香蕉"]
# 位置编码:每个词对应一个位置
# "猫" → [1, 0, 0, 0, 0] # 第1个位置是1,其他是0
# "狗" → [0, 1, 0, 0, 0] # 第2个位置是1,其他是0
# "苹果" → [0, 0, 0, 1, 0] # 第4个位置是1,其他是0
问题:这只是"位置编码",没有语义信息!
"猫" = [1, 0, 0, 0, 0]
"狗" = [0, 1, 0, 0, 0]
余弦相似度 = 0 (完全不相似)
但实际上"猫"和"狗"都是动物,应该很相似!
更智能的例子:语义向量
# 语义编码:每个词用"含义"来表示
# 维度:[动物性, 植物性, 可食用性, 宠物性]
cat = np.array([0.9, 0.1, 0.7, 0.9]) # 猫:动物性高,可食用(猫肉?),是宠物
dog = np.array([0.8, 0.2, 0.6, 0.9]) # 狗:动物性高,可食用(狗肉?),是宠物
apple = np.array([0.1, 0.9, 0.9, 0.0]) # 苹果:植物性高,可食用,不是宠物
# 计算相似度
print(f"猫 vs 狗: {cosine_similarity(cat, dog):.3f}") # ≈ 0.97(很相似!)
print(f"猫 vs 苹果: {cosine_similarity(cat, apple):.3f}") # ≈ 0.15(不太相似)
这就是文本向量化的威力:把"语义"变成"可计算的数值"!
3.3 向量化方法演进
演进概览
文本向量化的三种主要方法:
[BoW] ───→ [TF-IDF] ───→ [Word Embedding]
(词袋模型) (词频权重) (词向量嵌入)
简单粗暴 加入词重要性 蕴含语义信息
无语义 部分语义 深度语义
BoW(词袋模型)—— 最简单的方法
原理:把文本看成"一袋词",不考虑顺序,只管词出现了几次。
文本1: "Python 是 编程 语言"
文本2: "Java 是 编程 语言"
词表: [Python, Java, 是, 编程, 语言]
向量化:
from sklearn.feature_extraction.text import CountVectorizer
# 文档集合
docs = [
"Python 是 编程 语言",
"Java 是 编程 语言",
]
# BoW 向量化
vectorizer = CountVectorizer()
bow_matrix = vectorizer.fit_transform(docs)
print("词表:", vectorizer.get_feature_names_out())
# 输出: ['Python', 'Java', '是', '编程', '语言']
print("BoW矩阵:")
print(bow_matrix.toarray())
# 输出:
# [[1 0 1 1 1] # Python文档: Python=1, Java=0, 是=1, 编程=1, 语言=1
# [0 1 1 1 1]] # Java文档: Python=0, Java=1, 是=1, 编程=1, 语言=1
BoW 的优缺点
| 优点 | 缺点 |
|---|---|
| 简单直观 | 忽略词序 |
| 容易实现 | "我爱你"和"你爱我"向量完全相同 |
| 计算速度快 | 所有词同等重要 |
| 适合基线模型 | 无法捕捉语义 |
TF-IDF —— 加入词的重要性
问题:BoW 中"Python"和"的"权重相同,这不合理!
TF-IDF = 词频(TF) × 逆文档频率(IDF)
TF = 这个词在本文中出现了多少次
IDF = 这个词在所有文档中多不多(越多越不重要)
TF-IDF = TF × IDF
为什么有效?
・高频出现 ≠ 重要
"的"在所有文章都出现 → TF高, IDF低 → TF-IDF低 ❌ 停用词
・罕见词 ≠ 不重要
"TensorFlow"只在AI文章出现 → TF低, IDF高 → TF-IDF高 ✅ 重要词
・既高频又独特 = 真正重要的词
TF-IDF 示例:
from sklearn.feature_extraction.text import TfidfVectorizer
docs = [
"Python 编程 语言",
"Python Python Python", # Python出现3次
"Java 编程 语言",
]
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(docs)
print("词表:", tfidf_vectorizer.get_feature_names_out())
print("\nTF-IDF矩阵:")
print(tfidf_matrix.toarray())
# 观察:Python在第2篇文档中出现3次,但TF-IDF值不是最高的
# 因为"Python"在所有文档都出现了,IDF值较低
Word Embedding(词嵌入)—— 蕴含语义
BoW 和 TF-IDF 的根本问题
"猫" → [1, 0, 0, ...] # 只是"位置编码"
"狗" → [0, 1, 0, ...] # 猫和狗的位置不同
"小猫" → [0, 0, 1, ...] # 但它们语义相近,向量却正交!
问题:无法表达语义相似性!
Embedding 的思想
不再用"位置"表示词,而是用"语义空间"表示词
语义空间中的位置:
↑
动物 植物
| ↑ 猫 ↑ 狗 ↑ 苹果
| ↗ ↗ ↑
| ↗ ↗ ← 语义相近的词距离近 →
| ↗ ↗ →
|——————————————————————————————————————→
0 抽象 具体
词嵌入的效果
# 假设我们用预训练模型得到了词的语义向量
# 实际中向量通常是 50/100/300 维,这里用3维举例
word_vectors = {
"猫": [0.9, 0.1, 0.2], # 动物属性高
"狗": [0.8, 0.3, 0.1], # 动物属性高
"苹果": [0.1, 0.2, 0.9], # 水果属性高
"Python": [0.1, 0.0, 0.9], # 编程属性高
"Java": [0.1, 0.0, 0.85], # 编程属性高
}
print("=== 语义相似度 ===")
print(f"猫 vs 狗: {cosine_similarity(word_vectors['猫'], word_vectors['狗']):.3f}")
# 输出: 猫 vs 狗: 0.972(非常相似!都是动物)
print(f"猫 vs 苹果: {cosine_similarity(word_vectors['猫'], word_vectors['苹果']):.3f}")
# 输出: 猫 vs 苹果: 0.149(不太相似!)
print(f"Python vs Java: {cosine_similarity(word_vectors['Python'], word_vectors['Java']):.3f}")
# 输出: Python vs Java: 0.998(非常相似!都是编程语言)
📖 第四部分:文本处理的完整流程
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 数学公式速查
| 方法 | 公式 | 含义 |
|---|---|---|
| 向量加法 | [1,2] + [3,4] = [4,6] | 对应位置相加 |
| 向量数乘 | 2 × [1,2] = [2,4] | 每个元素乘以标量 |
| 向量点积 | [1,2] · [3,4] = 11 | 对应相乘再求和 |
| 向量长度 | [3,4] | |
| 余弦相似度 | cos(θ) = (A·B) / (|A|×|B|) | 向量相似程度 |
📝 课后作业
第一部分:文本数据基础(1-2道)
题目1
在Python中,用两种方式表示"Hello":
- 用
ord()函数打印每个字符的ASCII码 - 用
chr()函数验证:字符65对应的是大写字母A
题目2
思考题:为什么计算机擅长处理图像矩阵,却不擅长处理文本?请从"数据的表示形式"和"语义理解"两个角度说明原因。
第二部分:向量基础(1-2道)
题目3
已知向量 A = [3, 4],B = [1, 2]:
- 计算 A + B 的结果
- 计算 2 × A 的结果
- 计算 A 的长度(模)
题目4
有两个向量:A = [1, 2, 3],B = [4, 5, 6]
- 计算它们的点积 A · B
- 计算它们的余弦相似度
- 如果 A = [1, 0],B = [0, 1],它们的余弦相似度是多少?为什么?
第三部分:文本向量化(1-2道)
题目5
假设有以下3个文档:
- Doc1: "Python 是 编程 语言"
- Doc2: "Java 是 编程 语言"
- Doc3: "Python Python Python"
使用BoW模型,词表是什么?每个文档的向量表示是什么?
题目6
思考题:BoW模型有哪些缺点?请至少列出2个,并说明为什么这些缺点在某些场景下会成为问题。
附加题(选做)
题目7
阅读以下代码,理解TF-IDF的工作原理:
from sklearn.feature_extraction.text import TfidfVectorizer
docs = ["Python 编程", "Java 编程", "Python Python"]
tfidf = TfidfVectorizer()
matrix = tfidf.fit_transform(docs)
print("词表:", tfidf.get_feature_names_out())
print("TF-IDF矩阵:")
print(matrix.toarray())
运行代码并回答:
- 为什么"Python"在Doc3中的TF-IDF值不是最高(假设Doc1和Doc2的值更小)?
- "Java"在Doc2中的TF-IDF值是多少?解释原因。
🚀 下节预告
下一节我们将进入 3-2-2:分词与文本清洗, 学习:
- 如何用 jieba 进行中文分词
- 停用词的作用与过滤方法
- 代码实战:清洗豆瓣评论数据
🎯 记住:文本向量化的核心目标是把"符号"变成"可计算的数值向量"!