《动手学深度学习》-52文本预处理实现

原始文本 → 规范化文本 → token 序列 → 词表(token↔id) → 数字序列(id 序列)

核心:构建词表(Vocab)

词表是文本数字化的关键,它维护两种映射:

  1. token → index(token_to_idx):把词映射成数字 id

  2. index → token(idx_to_token):把数字 id 还原成词

构建词表时,一般要处理三个关键机制:

  1. 未知词 <unk>

现实中一定会遇到训练时没见过的词。因此词表会预留一个特殊 token:<unk>,代表"未知词"。

当查不到某个 token 时,用 <unk> 的 id 代替。常见约定:<unk> 的 id 是 0。

  1. 保留 token(reserved_tokens)

有些 token 是任务必需的特殊标记,比如:

  • <pad>:填充到固定长度

  • <bos>:句子开始

  • <eos>:句子结束

  • <mask>:掩码(BERT 类模型)

这些 token 通常放在词表最前面(紧跟 <unk>),确保它们有稳定的 id。

  1. 最小频次过滤(min_freq)

文本里有大量低频词,如果全部纳入词表:

  • 词表会非常大,占内存、训练慢

  • 很多低频词对模型帮助小,但会引入稀疏噪声

因此常设置 min_freq,只保留出现次数 ≥ min_freq 的 token。低频词统一用 <unk> 替代。

复制代码
2.代码

def read_time_machine(payh='D:/PycharmDocument/limu/data/timemachine.txt'):
    with open(payh,'r',encoding='utf-8') as f:
        lines=f.readlines()
    return [re.sub('[^A-Za-z]+',' ',line).strip().lower() for line in lines]
lines=read_time_machine()
# print(lines[10])
# print(len(lines))
def tokenize(lines,token='word'):
    if token=='word':
        return [line.split() for line in lines]
    elif token=='char':
        return [list(line) for line in lines]
    else:
        print('wrong token')
tokens=tokenize(lines,'word')
# for i in range(11):
#     print(tokens[i])
复制代码
#词汇表,将字符串映射到数字索引
class Vocab:
    def __init__(self,tokens=None,min_freq=0,reserved_tokens=None):
        if tokens is None:
            tokens=[]
        if reserved_tokens is None:
            reserved_tokens=[]
        counter=count_cropus(tokens)
        self.token_freqs=sorted(counter.items(),key=lambda x:x[1],reverse=True)#讲词频排序
        self.unk,uniq_tokens=0,['<unk>']+reserved_tokens#初始化,uniq_tokens起始设置为unk和reserved_tokens
        uniq_tokens+=[token for token,freq in self.token_freqs#讲词频高且不在reserved_tokens里的token依次加载,此时为全部的token
                      if freq>=min_freq and token not in reserved_tokens]
        self.idx_to_token,self.token_to_idx=[],dict()
        for token in uniq_tokens:
            self.idx_to_token.append(token)
            self.token_to_idx[token]=len(self.idx_to_token)-1#构建词汇-数字索引,一一对应
    def __len__(self):
        return len(self.token_to_idx)
    def __getitem__(self,tokens):#获取数字
        if not isinstance(tokens,(list,tuple)):
            return self.token_to_idx.get(tokens,self.unk)
        return [self.__getitem__(token) for token in tokens]
    def to_tokens(self,indices):#获取char
        if not isinstance(indices,(list,tuple)):
            return self.idx_to_token[indices]
        return [self.idx_to_token[index] for index in indices]
def count_cropus(tokens):
    if len(tokens)==0 or isinstance(tokens[0],list):
        tokens=[token for line in tokens for token in line]
    return collections.Counter(tokens)
vocab=Vocab(tokens)
# print(list(vocab.token_to_idx.items())[:10])
复制代码
for i in [0,10]:
    print(tokens[i])
    print(vocab[tokens[i]])
复制代码
def load_crops_time_machine(max_tokens=-1):
    lines=read_time_machine()
    tokens=tokenize(lines,'char')
    vocab=Vocab(tokens)
    corpus=[vocab[token] for line in tokens for token in line]
    if max_tokens>0:
        corpus=corpus[:max_tokens]
    return corpus,vocab
corpus,vocab=load_crops_time_machine()
print(len(corpus))
print(len(vocab))
相关推荐
Miao121315 小时前
某海外住宿平台如何在大规模场景下实现指标一致性:Minerva 指标平台实践
大数据·数据库·人工智能
冬奇Lab5 小时前
每日一个开源项目(第164篇):毕昇(BISHENG)- 面向企业的开源 LLM DevOps 平台
人工智能·开源·agent
SeaTunnel5 小时前
从 Python Script 地狱到标准化数据集成框架
大数据·开发语言·python·程序员·代码·seatunnel
深度研习笔记5 小时前
OpenCV工业视觉实战09|项目EXE打包+工控机无环境部署+后台常驻运行,彻底脱离Python环境,完成项目最终交付
python·opencv·webpack
CCPC不拿奖不改名5 小时前
大模型推理架构与开源生态知识整理
数据库·windows·python·架构·langchain·开源·github
声讯电子5 小时前
录音笔AI降噪方案:从录得到到听得清的听觉革命
人工智能·语音识别
小小测试开发6 小时前
Playwright vs Selenium vs Cypress:从浏览器协议到 API 设计的全面对比与实测
人工智能·selenium·测试工具
Marst Code6 小时前
(python)2026Plotly 库评估:交互式可视化到底值不值得引入?
开发语言·python
Ai_easygo6 小时前
AI Agent开发入门——从ReAct到Tool Calling,拆解Agent的底层运行逻辑
前端·人工智能·react.js
databook6 小时前
当散点图不够用时:用 t-SNE 可视化多维数据
python·数据分析·数据可视化