文本分析 - 词汇统计
1 课程概览
本课演示如何统计训练集和测试集中的词汇总数(去重后的不同单词数量)。使用链式编程 set(chain(*map(lambda x: jieba.lcut(x), sentences))) 实现高效统计,综合运用 map、chain、set 三个函数。
2 核心概念与定义
- 词汇总数(Vocabulary Size):语料库中去重后的不同单词数量。
- 链式编程(Chaining):将多个函数调用组合在一起,如
set(chain(*map(...)))。
3 模型与算法详解
词汇统计流程
- 读取数据:训练集和测试集
- 切词:使用
jieba.lcut()对每个句子切词 - 合并:使用
chain()合并所有句子的切词结果 - 去重:使用
set()去除重复词汇 - 统计:使用
len()获取词汇总数
链式编程拆解
# 完整链式写法
train_vocab = set(chain(*map(lambda x: jieba.lcut(x), train_data["sentence"])))
train_vocab_count = len(train_vocab)
拆解步骤:
map(lambda x: jieba.lcut(x), sentences):对每个句子切词,返回迭代器*:解包,将迭代器中的每个列表作为参数传给 chainchain(...):合并所有切词结果set(...):去重len(...):统计数量
灵活写法建议
将 len() 放在最后,而非链式内部,以便复用 train_vocab:
# 推荐:先获取去重词汇,再统计
train_vocab = set(chain(*map(lambda x: jieba.lcut(x), train_data["sentence"])))
count = len(train_vocab) # 需要长度时再加 len
4 数学原理与推导
词汇总数计算
给定句子集合 $S = {s_1, s_2, ..., s_n}$,每个句子切词后为 $W_i = {w_{i1}, w_{i2}, ..., w_{im}}$:
$$\text{Vocab} = \bigcup_{i=1}^{n} W_i$$
$$\text{VocabSize} = |\text{Vocab}|$$
5 代码示例
import pandas as pd
import jieba
from itertools import chain
# 定义函数:获取训练集和测试集的词汇总数
def dm04_get_word_count():
# 1. 读取训练集和测试集
train_data = pd.read_csv("./data/train.tsv", sep="\t")
test_data = pd.read_csv("./data/test.tsv", sep="\t")
# 2. 统计训练集的词汇总数(去重)
train_vocab = set(
chain(
*map(lambda x: jieba.lcut(x), train_data["sentence"])
)
)
print(f"训练集不同词汇总数为: {len(train_vocab)}")
# 3. 统计测试集的词汇总数(去重)
test_vocab = set(
chain(
*map(lambda x: jieba.lcut(x), test_data["sentence"])
)
)
print(f"测试集不同词汇总数为: {len(test_vocab)}")
# 测试
if __name__ == "__main__":
dm04_get_word_count()
链式编程拆解示例
# 逐步拆解
sentences = train_data["sentence"]
# 步骤1:切词(map 返回迭代器)
words_iter = map(lambda x: jieba.lcut(x), sentences)
# 例如:[["早餐", "不好"], ["服务", "到位"], ...]
# 步骤2:解包并合并(chain)
all_words = chain(*words_iter)
# 例如:["早餐", "不好", "服务", "到位", ...]
# 步骤3:去重(set)
unique_words = set(all_words)
# 例如:{"早餐", "不好", "服务", "到位", ...}
# 步骤4:统计数量(len)
count = len(unique_words)
6 重难点与易错提醒
- ❗重点:链式编程
set(chain(*map(lambda x: jieba.lcut(x), sentences)))是核心写法。 - ⚠️易错:
*解包操作不可省略,否则 chain 接收的是整个迭代器而非各个列表。 - ⚠️易错:
set()用于去重,len()用于统计数量。 - 💡深入理解:建议将
len()放在最后,以便复用train_vocab做其他操作(如生成词向量索引)。 - 💡深入理解:链式编程大幅减少代码量,提高可读性。
7 课堂问答精选
Q1:如何统计训练集的词汇总数?
A:使用链式编程 len(set(chain(*map(lambda x: jieba.lcut(x), train_data["sentence"]))))。步骤:切词 → 合并 → 去重 → 统计。
Q2:为什么使用 * 解包?
A:map 返回的是迭代器,包含多个列表。* 解包将每个列表作为单独参数传给 chain,否则 chain 会将整个迭代器视为一个元素。
Q3:为什么建议将 len() 放在最后?
A:如果将 len() 写在链式内部,只能获取长度。放在最后可以先获取 train_vocab(去重词汇集合),再按需统计长度或做其他操作(如生成索引),更灵活。
8 本课小结
- 词汇总数:去重后的不同单词数量。
- 链式编程:
set(chain(*map(lambda x: jieba.lcut(x), sentences)))。 - 步骤:切词(map)→ 合并(chain)→ 去重(set)→ 统计(len)。
*解包:将迭代器中的列表作为参数传给 chain。- 建议将
len()放最后,以便复用去重词汇集合。
9 延伸思考
- 如何利用去重词汇集合生成词向量索引?
- 词汇总数对模型选择有什么影响?