怎么做网站代拍,2023网页设计十大品牌,画册设计制作,基于php的网站开发英文文献系列文章目录
例如#xff1a;第一章 Python 机器学习入门之pandas的使用 文章目录 系列文章目录一、理论部分二、代码读取数据集词元化词表整合所有功能小结练习 一、理论部分
对于序列数据处理问题#xff0c;我们在序列处理中评估了所需的统计工具和预测时面临的挑战。 …系列文章目录
例如第一章 Python 机器学习入门之pandas的使用 文章目录 系列文章目录一、理论部分二、代码读取数据集词元化词表整合所有功能小结练习 一、理论部分
对于序列数据处理问题我们在序列处理中评估了所需的统计工具和预测时面临的挑战。 这样的数据存在许多种形式文本是最常见例子之一。 例如一篇文章可以被简单地看作一串单词序列甚至是一串字符序列。 本节中我们将解析文本的常见预处理步骤。 这些步骤通常包括
将文本作为字符串加载到内存中。将字符串拆分为词元如单词和字符。建立一个词表将拆分的词元映射到数字索引。将文本转换为数字索引序列方便模型操作。
二、代码
import collections
import re
from d2l import torch as d2l读取数据集
首先我们从H.G.Well的时光机器中加载文本。 这是一个相当小的语料库只有30000多个单词但足够我们小试牛刀而现实中的文档集合可能会包含数十亿个单词。 下面的函数(将数据集读取到由多条文本行组成的列表中)其中每条文本行都是一个字符串。 为简单起见我们在这里忽略了标点符号和字母大写。
# 将时间机器数据集的下载链接和哈希值添加到数据仓库中
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])# 文本总行数: 3221
the time machine by h g wells
twinkled and his usually pale face was flushed and animated the词元化
下面的tokenize函数将文本行列表lines作为输入列表中的每个元素是一个文本序列如一条文本行。 [每个文本序列又被拆分成一个词元列表]词元token是文本的基本单位。 最后返回一个由词元列表组成的列表其中的每个词元都是一个字符串string。
def tokenize(lines, tokenword): #save将文本行拆分为单词或字符词元# 如果指定的词元类型是 wordif token word:# 将每一行拆分为单词返回一个包含单词列表的列表return [line.split() for line in lines]# 如果指定的词元类型是 charelif token char:# 将每一行拆分为字符返回一个包含字符列表的列表return [list(line) for line in lines]else:# 如果词元类型未知打印错误信息print(错误未知词元类型 token)# 调用 tokenize 函数将文本行拆分为词元默认使用单词作为词元
tokens tokenize(lines)# 打印前 11 行的词元
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]
词表
词元的类型是字符串而模型需要的输入是数字因此这种类型不方便模型使用。 现在让我们[构建一个字典通常也叫做词表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)1. counter.items()counter 是一个字典包含了词元及其对应的频率。items()方法返回一个包含字典中所有键值对的视图每个键值对以元组的形式表示例如(word, frequency)。2. sorted(..., keylambda x: x[1], reverseTrue):sorted() 函数用于对可迭代对象进行排序。这里对 counter.items() 返回的元组列表进行排序。keylambda x: x[1]:key参数指定了排序的依据。这里使用了一个匿名函数lambda 函数它接受一个元组 x并返回该元组的第二个元素即频率。因此排序将基于频率进行。reverseTrue:设置为 True 表示按降序排序即频率高的词元排在前面。3. self._token_freqs ..:将排序后的结果赋值给 self._token_freqs这是一个包含词元及其频率的列表按频率从高到低排列。总结:这行代码的主要功能是生成一个按频率降序排列的列表方便后续处理例如在构建词表时可以优先考虑高频词元。# 未知词元的索引为0self.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: # 如果频率低于最小频率则停止添加breakif 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):返回词表中词元的数量print(调用了len函数) # 打印调试信息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 0 # 返回未知词元的索引propertydef token_freqs(self):返回词元的频率return self._token_freqs # 返回统计的词元频率def count_corpus(tokens): #save统计词元的频率# 这里的tokens是1D列表或2D列表if len(tokens) 0 or isinstance(tokens[0], list): # 如果tokens为空或是二维列表# 将词元列表展平成一个列表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])[(unk, 0), (the, 1), (i, 2), (and, 3), (of, 4), (a, 5), (to, 6), (was, 7), (in, 8), (that, 9)]现在我们可以(将每一条文本行转换成一个数字索引列表)。
for i in [0, 10]:print(文本:, tokens[i])print(索引:, vocab[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时光机器语料库的词表。 我们在这里所做的改变是
为了简化后面章节中的训练我们使用字符而不是单词实现文本词元化时光机器数据集中的每个文本行不一定是一个句子或一个段落还可能是一个单词因此返回的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]# 如果指定了最大词元数则截取前 max_tokens 个词元if max_tokens 0:corpus corpus[:max_tokens]# 返回词元索引列表和词表return corpus, vocab# 调用函数加载时光机器数据集并获取词元索引列表和词表
corpus, vocab load_corpus_time_machine()# 输出词元索引列表和词表的长度
len(corpus), len(vocab) #前面的值为170580后面的为28
调用了len函数
(170580, 28)list(vocab.token_to_idx.items())[:10][(unk, 0),( , 1),(e, 2),(t, 3),(a, 4),(i, 5),(n, 6),(o, 7),(s, 8),(h, 9)]小结
文本是序列数据的一种最常见的形式之一。为了对文本进行预处理我们通常将文本拆分为词元构建词表将词元字符串映射为数字索引并将文本数据转换为词元索引以供模型操作。
练习
词元化是一个关键的预处理步骤它因语言而异。尝试找到另外三种常用的词元化文本的方法。在本节的实验中将文本词元为单词和更改Vocab实例的min_freq参数。这对词表大小有何影响