第N2周:构建词典
- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
因为我安装的pytorch2.7.0+cpu,最多能安装成功torchtext版本是0.6.0,总是报错,所以就手动构建词汇表类。
# 导入必要的库
from collections import Counter # 用于词频统计
import jieba # 中文分词库
import re # 正则表达式库
import torch # PyTorch 库
import datetimeprint(datetime.datetime.now())
# 示例文本数据
data = ["孤城鏖战数万兵","十三将士归玉门"]# 中文分词方法,使用 jieba 分词工具
tokenizer = jieba.lcut# 如果有自定义词典,可以通过此方法加载
# jieba.load_userdict("my_dict.txt")# 去除标点符号的函数
def remove_punctuation(text):"""使用正则表达式去除文本中的标点符号。"""return re.sub(r'[^\w\s]', '', text) # 匹配所有非字母、数字或空格的字符,替换为空# 假设我们有一个简单的停用词表,包含一些无意义的常用词
stopwords = set(["的", "这", "是" # 停用词示例
])# 去除停用词的函数
def remove_stopwords(words):"""从分词后的列表中去除停用词。"""return [word for word in words if word not in stopwords] # 保留不在停用词表中的词# 生成分词迭代器,用于构建词汇表
def yield_tokens(data):"""对文本数据进行分词并去除停用词和标点符号,生成词汇列表。"""for text in data:# 使用 jieba 对文本进行分词words = tokenizer(text)# 去除停用词words = remove_stopwords(words)# 去除标点符号words = [remove_punctuation(word) for word in words]# 过滤掉空字符串words = [word for word in words if word]# 生成一个词汇列表,供词汇表构建使用yield words# 手动构建词汇表类
class Vocab:def __init__(self, tokens_iterator, specials=["<unk>"], min_freq=1):"""手动构建词汇表参数:tokens_iterator: 分词后的迭代器specials: 特殊标记列表min_freq: 最小词频阈值"""# 统计词频counter = Counter()for tokens in tokens_iterator:counter.update(tokens)# 构建词汇表self.itos = [] # index to stringself.stoi = {} # string to index# 添加特殊标记for special in specials:if special not in self.stoi:self.itos.append(special)self.stoi[special] = len(self.itos) - 1# 添加满足最小词频的词for token, freq in counter.items():if freq >= min_freq and token not in self.stoi:self.itos.append(token)self.stoi[token] = len(self.itos) - 1# 设置默认索引(未知词索引)self.unk_index = self.stoi.get("<unk>", 0)def __getitem__(self, token):"""获取token的索引,如果token不存在则返回未知词索引"""return self.stoi.get(token, self.unk_index)def __len__(self):"""返回词汇表大小"""return len(self.itos)def get_stoi(self):"""返回词到索引的映射字典"""return self.stoidef get_itos(self):"""返回索引到词的映射列表"""return self.itos# 使用自定义的Vocab类来构建词汇表
vocab = Vocab(yield_tokens(data), specials=["<unk>"])# 打印词汇表的大小和词汇表内部的映射关系
print("词典大小:", len(vocab)) # 输出词汇表中不同词汇的数量
print("词典内部映射:", vocab.get_stoi()) # 输出词到索引的映射# 示例文本
text = "一生何求百岁名,四海皆兄弟。"
# 使用 jieba 对示例文本进行分词
words = remove_stopwords(jieba.lcut(text)) # 去除停用词后的词汇列表
words = [remove_punctuation(word) for word in words] # 去除标点符号
words = [word for word in words if word] # 过滤空字符串print("\n")
# 打印分词后的文本
print("jieba分词后的文本:", jieba.lcut(text)) # 输出分词结果
# 打印去除停用词后的文本
print("去除停用词后的文本:", words) # 输出去除停用词后的结果
# 将文本中的词转换成数字索引
print("数字化后的文本:", [vocab[word] for word in words]) # 输出数字化后的词汇索引
运行结果如下
2025-10-31 21:47:07.653140
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\pozhen\AppData\Local\Temp\jieba.cache
Loading model cost 0.476 seconds.
Prefix dict has been built successfully.
词典大小: 9
词典内部映射: {'<unk>': 0, '孤城': 1, '鏖战': 2, '数万': 3, '兵': 4, '十三': 5, '将士': 6, '归': 7, '玉门': 8}jieba分词后的文本: ['一生何求', '百岁', '名', ',', '四海', '皆', '兄弟', '。']
去除停用词后的文本: ['一生何求', '百岁', '名', '四海', '皆', '兄弟']
数字化后的文本: [0, 0, 0, 0, 0, 0]进程已结束,退出代码为 0
