网站模版上线需要什么意思,淘特网官方网站下载,网站域名的后缀,深圳考试培训网站建设#x1f468;#x1f393;作者简介#xff1a;一位即将上大四#xff0c;正专攻机器学习的保研er #x1f30c;上期文章#xff1a;机器学习深度学习——序列模型#xff08;NLP启动#xff01;#xff09; #x1f4da;订阅专栏#xff1a;机器学习作者简介一位即将上大四正专攻机器学习的保研er 上期文章机器学习深度学习——序列模型NLP启动 订阅专栏机器学习深度学习 希望文章对你们有所帮助 里面的算法写起来也不难但是对于算法小白来说还是要点时间不过花点时间也能搞明白。 文本预处理 步骤读取数据集词元化词表整合所有功能小结 步骤
一篇文章可以被简单地看作一串单词序列甚至是一串字符序列我们将进行解析文本的预处理操作步骤包括 1、将文本作为字符串加载到内存中。 2、将字符串拆分为词元如单词和字符。 3、建立一个词表将拆分的词元映射到数字索引。 4、将文本转换为数字索引序列方便模型操作。
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]lines read_time_machine()
print(f# 文本总行数: {len(lines)})
print(lines[0])
print(lines[10])
运行结果
词元化
下面的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])运行结果 [‘the’, ‘time’, ‘machine’, ‘by’, ‘h’, ‘g’, ‘wells’] [] [] [] [] [‘i’] [] [] [‘the’, ‘time’, ‘traveller’, ‘for’, ‘so’, ‘it’, ‘will’, ‘be’, ‘convenient’, ‘to’, ‘speak’, ‘of’, ‘him’] [‘was’, ‘expounding’, ‘a’, ‘recondite’, ‘matter’, ‘to’, ‘us’, ‘his’, ‘grey’, ‘eyes’, ‘shone’, ‘and’] [‘twinkled’, ‘and’, ‘his’, ‘usually’, ‘pale’, ‘face’, ‘was’, ‘flushed’, ‘and’, ‘animated’, ‘the’] 词表
模型更喜欢使用的输入不是字符串而是数字因此我们构造一个字典就好了这个字典就叫词表。 步骤如下 1、将训练集中的文档合并在一起对它们的唯一词元进行统计得到的统计结果称为语料corpus 2、根据每个唯一词元的出现频率为其分配数字索引很少出现的词元可以被移除来降低复杂度 3、不存在或者已删除的词元将映射到特定的位置词元 u n k unk unk 4、我们就可以增加一个列表来保存那些被保留的词元如 p a d 填充词元 b o s 序列开始词元 e o s 序列结束词元 pad填充词元\\ bos序列开始词元\\ eos序列结束词元 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] # 提取每一行的每个词元其实也就是一个双层循环# 返回一个可以用来计数的APIreturn collections.Counter(tokens)我们首先使用数据集作为语料库来构建词表然后打印一下前几个高频词元以及他们的索引
vocab Vocab(tokens)
print(list(vocab.token_to_idx.items())[:10])输出结果 现在我们可以将每一条文本行转换成一个数字索引列表
for i in [0, 10]:print(文本:, tokens[i])print(索引:, vocab.__getitem__(tokens[i]))结果如下 文本: [‘the’, ‘time’, ‘machine’, ‘by’, ‘h’, ‘g’, ‘wells’] 索引: [1, 19, 50, 40, 2183, 2184, 400] 文本: [‘twinkled’, ‘and’, ‘his’, ‘usually’, ‘pale’, ‘face’, ‘was’, ‘flushed’, ‘and’, ‘animated’, ‘the’] 索引: [2186, 3, 25, 1044, 362, 113, 7, 1421, 3, 1045, 1] 整合所有功能
在使用上述函数时我们将所有功能打包到load_corpus_time_machine函数中该函数返回corpus词元索引列表和vocab词表我们在这边做出改变 1、为了简化以后的村联这里使用字符来实现词元化 2、数据集中的每个文本行不一定是一个句子或一个段落还可能是一个单词因此返回的corpus仅处理为单个列表而不是使用多词元列表构成的一个列表。
from d2l import torch as d2ldef load_corpus_time_machine(max_tokens-1): #save返回《时光机器》数据集的词元索引列表和词表lines d2l.read_time_machine()tokens d2l.tokenize(lines, char)vocab d2l.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))
运行结果 170580 28 小结
1、文本是序列数据的一种最常见形式之一。 2、为了对文本进行预处理我们通常将文本拆分为词元构建词表将词元字符串映射为数字索引并将文本数据转换为词元索引以供模型操作。