news 2026/5/1 9:43:43

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

作者头像

张小明

前端开发工程师

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/5/1 6:26:12

零基础如何学网络安全?超详细攻略,带你从入门到精通

一、学习建议 1.了解基础概念&#xff1a; 开始之前&#xff0c;了解网络安全的基本概念和术语是很重要的。你可以查找网络安全入门教程或在线课程&#xff0c;了解网络安全领域的基本概念&#xff0c;如黑客、漏洞、攻击类型等。 2.网络基础知识&#xff1a; 学习计算机网…

作者头像 李华
网站建设 2026/4/30 10:01:19

【2026实测】快降重降 AI 率:格式零损伤,学术改写高效又规范

摘要笔者以工科《计算机技术应用下的电气自动化控制系统设计分析》论文为测试对象&#xff0c;针对工科论文包含表格、公式、数据图表的特点&#xff0c;使用快降重 Pro 版进行降 AI 率处理&#xff0c;实测其在维普、PaperPass 等工科常用检测平台的效果。结果显示&#xff0c…

作者头像 李华
网站建设 2026/5/1 8:37:12

2026年 IT 转行就业,为何首选网络安全?五大核心优势深度解析

2025年IT转行/就业为什么首先要选网络安全&#xff1f; 记得曾经有人说过这样一个俗语&#xff1a;三百六十行&#xff0c;行行转IT。或许听到这个话的时候会觉得是一句玩笑话&#xff0c;但是浏览到网络上一些关于就业的文章&#xff0c;就能够明白这句话的真正意义所在。随着…

作者头像 李华
网站建设 2026/5/1 3:12:12

零基础怎么学网络安全?一文超详细详解,带你从入门到精通

一、学习建议 1.了解基础概念&#xff1a; 开始之前&#xff0c;了解网络安全的基本概念和术语是很重要的。你可以查找网络安全入门教程或在线课程&#xff0c;了解网络安全领域的基本概念&#xff0c;如黑客、漏洞、攻击类型等。 2.网络基础知识&#xff1a; 学习计算机网…

作者头像 李华
网站建设 2026/5/1 8:16:01

暗数据基础、挑战与管理策略

什么是暗数据&#xff1f;基础与挑战 暗数据和非结构化数据指的是同一事物。区别在于术语的指向对象不同。非结构化数据往往是面向工程师的术语。它指的是数据的结构特性&#xff0c;向工程师传达他们需要如何处理数据以使其可用。非结构化数据是未经提炼的数据&#xff0c;需…

作者头像 李华
网站建设 2026/5/1 5:44:21

毕设项目 stm32 wifi远程温控风扇系统

文章目录 0 前言1 主要功能2 系统架构3 核心软件设计3.3.2 初始化3.3.3 温度采集与显示 4 实现效果5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c…

作者头像 李华