泉州cms建站系统,wordpress后台登陆模板,市场调研报告怎么做,旅游网网站建设的管理注#xff1a;书中对代码的讲解并不详细#xff0c;本文对很多细节做了详细注释。另外#xff0c;书上的源代码是在Jupyter Notebook上运行的#xff0c;较为分散#xff0c;本文将代码集中起来#xff0c;并加以完善#xff0c;全部用vscode在python 3.9.18下测试通过书中对代码的讲解并不详细本文对很多细节做了详细注释。另外书上的源代码是在Jupyter Notebook上运行的较为分散本文将代码集中起来并加以完善全部用vscode在python 3.9.18下测试通过同时对于书上部分章节也做了整合。
Chapter8 Recurrent Neural Networks
8.2 Text Preprocessing
文本的预处理步骤通常包括
将文本作为字符串加载到内存中将字符串拆分为词元如单词和字符建立一个词表将拆分的词元映射到数字索引将文本转换为数字索引序列方便模型操作。
代码如下
import collections
import re
from d2l import torch as d2l#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]#使用正则表达式 re.sub([^A-Za-z], , line) 将每行中的非字母字符替换为空格并且多个连续的非字母字符被替换成一个空格#使用strip()去除每行开头和结尾的空格#使用lower()将字母转换为小写lines read_time_machine()
print(f# 文本总行数: {len(lines)})
print(lines[0])
print(lines[10])def tokenize(lines, tokenword): #save将文本行拆分为单词或字符词元(token)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])词元的类型是字符串而模型需要的输入是数字因此需要构建一个字典通常称为词表vocabulary用来将字符串类型的词元映射到从 0 0 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]property #property用于将类的方法转换为类的属性def 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(len(vocab))
print(list(vocab.token_to_idx.items())[:10])for i in [0, 10]:print(文本:, tokens[i])print(索引:, vocab[tokens[i]])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()
print(len(corpus), len(vocab))