小匠第一周期打卡笔记-Task02

一、文本预处理

预处理通常包括四个步骤:

  读入文本

  分词

  建立字典,将每个词映射到一个唯一的索引(index)

  将文本从词的序列转换为索引的序列,方便输入模型

读入文本:

 1 import collections
 2 import re
 3 
 4 def read_time_machine():
 5     with open('/home/kesci/input/timemachine7163/timemachine.txt', 'r') as f:
 6         lines = [re.sub('[^a-z]+', ' ', line.strip().lower()) for line in f]
 7     return lines
 8 
 9 
10 lines = read_time_machine()
11 print('# sentences %d' % len(lines))

分词:

  将一个句子划分成若干个词(token),转换为一个词的序列

 1 def tokenize(sentences, token='word'):
 2     """Split sentences into word or char tokens"""
 3     if token == 'word':
 4         return [sentence.split(' ') for sentence in sentences]
 5     elif token == 'char':
 6         return [list(sentence) for sentence in sentences]
 7     else:
 8         print('ERROR: unkown token type '+token)
 9 
10 tokens = tokenize(lines)
11 tokens[0:2]

建立字典:

  将字符串转换为数字。先构建一个字典(vocabulary),将每个词映射到一个唯一的索引编号

 1 class Vocab(object):
 2     def __init__(self, tokens, min_freq=0, use_special_tokens=False):
 3         counter = count_corpus(tokens)  # : 
 4         self.token_freqs = list(counter.items())
 5         self.idx_to_token = []
 6         if use_special_tokens:
 7             # padding, begin of sentence, end of sentence, unknown
 8             self.pad, self.bos, self.eos, self.unk = (0, 1, 2, 3)
 9             self.idx_to_token += ['', '', '', '']
10         else:
11             self.unk = 0
12             self.idx_to_token += ['']
13         self.idx_to_token += [token for token, freq in self.token_freqs
14                         if freq >= min_freq and token not in self.idx_to_token]
15         self.token_to_idx = dict()
16         for idx, token in enumerate(self.idx_to_token):
17             self.token_to_idx[token] = idx
18 
19     def __len__(self):
20         return len(self.idx_to_token)
21 
22     def __getitem__(self, tokens):
23         if not isinstance(tokens, (list, tuple)):
24             return self.token_to_idx.get(tokens, self.unk)
25         return [self.__getitem__(token) for token in tokens]
26 
27     def to_tokens(self, indices):
28         if not isinstance(indices, (list, tuple)):
29             return self.idx_to_token[indices]
30         return [self.idx_to_token[index] for index in indices]
31 
32 def count_corpus(sentences):
33     tokens = [tk for st in sentences for tk in st]
34     return collections.Counter(tokens)  # 返回一个字典,记录每个词的出现次数
1 '''vocab = Vocab(tokens)
2 print(list(vocab.token_to_idx.items())[0:10])
3 [('', 0), ('the', 1), ('time', 2), ('machine', 3), ('by', 4), ('h', 5), ('g', 6), ('wells', 7), ('i', 8), ('traveller', 9)]'''

将词转为索引:

  使用字典,将原文本中的句子从单词序列转换为索引序列

1 for i in range(8, 10):
2     print('words:', tokens[i])
3     print('indices:', vocab[tokens[i]])

小结:

  用现有工具进行分词:

    我们前面介绍的分词方式非常简单,它至少有以下几个缺点:

    1.   标点符号通常可以提供语义信息,但是我们的方法直接将其丢弃了
    2.   类似“shouldn't", "doesn't"这样的词会被错误地处理
    3.   类似"Mr.", "Dr."这样的词会被错误地处理

    我们可以通过引入更复杂的规则来解决这些问题,但是事实上,有一些现有的工具可以很好地进行分词,我们在这里简单介绍其中的两个:spaCyNLTK

    

  无论 use_special_token  参数是否为真,都会使用特殊token——<unk>,用来表示未登录词。

  句子长度统计与构建字典无关

  

  

猜你喜欢

转载自www.cnblogs.com/Dreamer-Jie/p/12306304.html