news 2026/9/7 18:25:22

文本预处理:从词元到数字索引

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
文本预处理:从词元到数字索引

文本是最常见的序列数据,一本书、一篇文章可以被认为是一串单词序列,甚至是一串字符序列。

常见的预处理步骤:

  1. 将文本作为字符串加载到内存;
  2. 将字符串拆分为词元(eg:单词与字符);
  3. 构建词表,将拆分的词元映射到唯一对应的数字索引
  4. 将文本转换为数字索引序列,形成语料库方便模型操作。

1.读取数据集

选择 H.G.Well 的《时光机器》The Time Machine作为数据集输入。

The Project Gutenberg eBook of The Time Machine, by H. G. Wells

该数据集仅包含30多万个单词,是一个相当小的语料库。

# load 文本数据(一本书) d2l.DATA_HUB['time_machine'] = (d2l.DATA_URL + 'timemachine.txt', '090b5e7e70c295757f55df93cb0a180b9691891a') def read_time_machine(): """将时间机器数据集加载到文本行的列表中""" with open(d2l.download('time_machine'), 'r') as f: lines = f.readlines() return [re.sub('[^A-Za-z]+', ' ', line).strip().lower() for line in lines] # 仅处理小写字母和空格 lines = read_time_machine() print(f'# 文本总行数: {len(lines)}') print(lines[0]) print(lines[10])

在处理中仅考虑小写字母和空格,不考虑其余标点符号。

2.词元化处理

将上面处理的文本行数据 lines 作为输入,列表的每一个元素都是一个文本行,将其拆分为词元列表 token(词元是文本的基本单位),返回一个由词元列表组成的列表。

# 每行字符串变为词元 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('错误:未知词元类型:' + token) tokens = tokenize(lines) for i in range(11): print(tokens[i])

文本拆分两种常见的方式就是单词与字符拆分:

主要区别
特性wordchar
基本单位以空格分割的单词单个字符
示例"hello world" ->['hello','world']"hello"->['h','e','l','l','o']
词表大小较大很小
未知词处理要特殊处理(<unk>标记)几乎没有未知字符
序列长度较短较长

3.词表的构建

为了便于模型的使用,将字符串对应到数字,因此构建一个字典用于将字符串类型的词元映射到从0开始的数字索引。

# 构建字典 class Vocab: """文本词表""" def __init__(self, tokens=None, min_freq=0, reserved_tokens=None):# min_freq最小出现频次 if tokens is None: tokens = [] if reserved_tokens is None: reserved_tokens = [] # 按出现频率排序 counter = count_corpus(tokens) self._token_freqs = sorted(counter.items(), key=lambda x: x[1], reverse=True) # 未知词元的索引为0 self.idx_to_token = ['<unk>'] + reserved_tokens self.token_to_idx = {token: idx for idx, token in enumerate(self.idx_to_token)} for token, freq in self._token_freqs: if freq < min_freq: break if token not in self.token_to_idx: self.idx_to_token.append(token) self.token_to_idx[token] = len(self.idx_to_token) - 1 def __len__(self): return len(self.idx_to_token) 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): # index-》tokens if not isinstance(indices, (list, tuple)): return self.idx_to_token[indices] return [self.idx_to_token[index] for index in indices] def unk(self): # 未知词元的索引为0 return 0 def token_freqs(self): return self._token_freqs def count_corpus(tokens): """统计词元的频率""" # 这里的tokens是1D列表或2D列表 if len(tokens) == 0 or isinstance(tokens[0], list): # 将词元列表展平成一个列表 tokens = [token for line in tokens for token in line] return collections.Counter(tokens) # 记录次数

对唯一词元进行统计,得到的结果为语料库(corpus);在创建词表的过程中将很少出现的词元进行移除处理,语料库中不存在或已被移除的任意词元都映射到特定的未知词元(unk)。

实例化Vocab类,使用时光机器数据集作为语料库构建词表,打印前十个高频词及其索引。

vocab = Vocab(tokens) # 调用Vocab类 print(list(vocab.token_to_idx.items())[:10])

将文本行转为数字索引列表以第一行与第十一行为例:

# 文本转为数字索引 for i in [0, 10]: print('文本:', tokens[i]) print('索引:', vocab[tokens[i]])

4.功能的整合

将上述函数整合进总函数 load_corpus_time_machine 中,返回corpus(词元索引列表)以及vocab(时光机器语料库的词表)。此处使用字符而非单词实现文本的词元化。

def load_corpus_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_corpus_time_machine() len(corpus), len(vocab) # vocab 26+1(空格)+1(未知unk) # (170580, 28)

如果是以单词实现的文本词元化,则结果为(32775, 4580),这也对应了前文表中提到的特性。

5.小结

  • 文本是序列数据最常见的形式之一;
  • 对文本进行预处理,我们将文本拆分为词元,构建词表将词元字符串映射为数字索引,并将文本数据转换为词元索引供模型操作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 1:35:30

Yolov7模型训练指南:从环境搭建到最终应用

1. 环境搭建1.1 【 设备与系统配置 】我使用的设备配置为V100显卡双卡&#xff0c;总显存64GB&#xff0c;操作系统为Ubuntu 18.04&#xff0c;Python版本为3.7.10。在这样的环境下&#xff0c;我可以顺利地进行yolov7模型的训练。1.2 【 代码获取与准备 】在搭建好环境后&…

作者头像 李华
网站建设 2026/9/2 22:38:20

Golang构建AI智能体社交网络:MoltBook分布式架构实战

引言 2026年初,全球首个专为AI智能体设计的社交网络平台MoltBook在科技圈引发轰动。在短短48小时内,超过15万个AI智能体涌入平台,自发形成了上万个主题社区(Submolts),甚至诞生了名为"龙虾教"(Crustafarianism)的虚拟宗教。这一现象级实验不仅展示了AI群体自…

作者头像 李华
网站建设 2026/8/29 7:25:57

Transformer架构深度解析

🧠 Transformer架构深度解析:从“注意力”到“理解”的革命 Transformer架构是人工智能领域近十年来最具颠覆性的创新之一,它不仅是GPT、BERT等大语言模型的基石,更是推动了自然语言处理乃至整个深度学习范式的变革。其核心思想完全抛弃了传统的循环(RNN)和卷积(CNN)…

作者头像 李华
网站建设 2026/8/21 20:27:16

最近在折腾C#和欧姆龙PLC通信,发现网上完整的HostLink协议实现案例不多,自己啃手册写了套基础通信框架。直接上干货,先扔个读取DM区的代码

C#上位机与omron欧姆龙 Host Link通信串口通讯实例 源码 通过和PLC用串口连接&#xff0c;可以读取写入欧姆龙PLC的数据寄存器DM&#xff08;批量也可以&#xff09;、输入输出CIO、辅助继电器WR,H保持继电器等。 c#基于VS2015以上版本 // 串口配置 SerialPort sp new Serial…

作者头像 李华