网站域名更换,搭建电商平台方案,开设计工作室赚钱吗,上海十大设计公司有哪些文章目录 文本预处理1.读取数据集2.词元化3.词表4.整合所有功能 文本预处理
学习视频#xff1a;文本预处理【动手学深度学习v2】
官方笔记#xff1a;文本预处理
对于序列数据处理问题#xff0c;在【序列模型】中评估了所需的统计工具和预测时面临的挑战#xff0c;这… 文章目录 文本预处理1.读取数据集2.词元化3.词表4.整合所有功能 文本预处理
学习视频文本预处理【动手学深度学习v2】
官方笔记文本预处理
对于序列数据处理问题在【序列模型】中评估了所需的统计工具和预测时面临的挑战这样的数据存在许多种形式文本是最常见例子之一例如一篇文章可以被简单地看作一串单词序列甚至是一串字符序列。 本节中我们将解析文本的常见预处理步骤。 这些步骤通常包括
1.将文本作为字符串加载到内存中
2.将字符串拆分为词元(如单词和字符)
3.建立一个词表将拆分的词元映射到数字索引
4.将文本转换为数字索引序列方便模型操作
1.读取数据集
import collections
import re
from d2l import torch as d2l首先从时光机器中加载文本这是一个相当小的语料库只有30000多个单词但足够我们小试牛刀 而现实中的文档集合可能会包含数十亿个单词。 下面的函数将数据集读取到由多条文本行组成的列表中其中每条文本行都是一个字符串。 为简单起见我们在这里忽略了标点符号和字母大写。
#save
d2l.DATA_HUB[time_machine] (d2l.DATA_URL timemachine.txt,090b5e7e70c295757f55df93cb0a180b9691891a)def read_time_machine(): #save将时间机器数据集加载到文本行的列表中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.词元化
下面的tokenize函数将文本行列表lines作为输入 列表中的每个元素是一个文本序列如一条文本行。 每个文本序列又被拆分成一个词元列表词元token是文本的基本单位。 最后返回一个由词元列表组成的列表其中的每个词元都是一个字符串string。
def tokenize(lines, tokenword): #save将文本行拆分为单词或字符词元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])3.词表
词元的类型是字符串而模型需要的输入是数字因此这种类型不方便模型使用。 现在让我们构建一个字典通常也叫做词表vocabulary 用来将字符串类型的词元映射到从0开始的数字索引中。 我们先将训练集中的所有文档合并在一起对它们的唯一词元进行统计 得到的统计结果称之为语料corpus。 然后根据每个唯一词元的出现频率为其分配一个数字索引。 很少出现的词元通常被移除这可以降低复杂性。 另外语料库中不存在或已删除的任何词元都将映射到一个特定的未知词元“unk”。 我们可以选择增加一个列表用于保存那些被保留的词元 例如填充词元“pad” 序列开始词元“bos” 序列结束词元“eos”。
class Vocab: #save文本词表def __init__(self, tokensNone, min_freq0, reserved_tokensNone):if tokens is None:tokens []if reserved_tokens is None:reserved_tokens []# 按出现频率排序counter count_corpus(tokens)self._token_freqs sorted(counter.items(), keylambda x: x[1],reverseTrue)# 未知词元的索引为0self.idx_to_token [unk] reserved_tokensself.token_to_idx {token: idxfor idx, token in enumerate(self.idx_to_token)}for token, freq in self._token_freqs:if freq min_freq:breakif token not in self.token_to_idx:self.idx_to_token.append(token)self.token_to_idx[token] len(self.idx_to_token) - 1def __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):if not isinstance(indices, (list, tuple)):return self.idx_to_token[indices]return [self.idx_to_token[index] for index in indices]propertydef unk(self): # 未知词元的索引为0return 0propertydef token_freqs(self):return self._token_freqsdef count_corpus(tokens): #save统计词元的频率# 这里的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)vocab Vocab(tokens)
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时光机器语料库的词表。 我们在这里所做的改变是
为了简化后面章节中的训练我们使用字符而不是单词实现文本词元化时光机器数据集中的每个文本行不一定是一个句子或一个段落还可能是一个单词因此返回的corpus仅处理为单个列表而不是使用多词元列表构成的一个列表。
def load_corpus_time_machine(max_tokens-1): #save返回时光机器数据集的词元索引列表和词表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, vocabcorpus, vocab load_corpus_time_machine()
len(corpus), len(vocab)