本文编译自towards data science,作者是Dave Currie,该作者用TensorFlow搭建了一个拼写检查器,以用于处理自然语言处理(NLP)的数据。各位圈友一起看看,他是怎么做到的?
机器学习的一个最重要的问题就是,我们需要干净的数据。自然语言处理项目存在着一个问题——使用人类书写的文本。而不幸的是,我们并不擅长写作。想象一下,如果在Reddit上的有关帖子和评论的数据集中存在着许多拼写错误,这对于机器来说,是不是有些不好处理呢?
因此,制作一个拼写检查器将会是一个非常有价值的项目,这将有助于缓解这些问题。
我们即将用于此项目的模型与我在文章“亚马逊评论中的文本汇总”(都是seq2seq模型)中写的是很相似的,但是我添加了一些额外的代码行,以便可以使用grid search来调整整个架构和超参数,并且可以使用TensorBoard来分析结果。如果你想要更详细地演示如何在你的代码中添加TensorBoard,请查看“使用TensorFlow和TensorBoard预测Movie Review Sentiment”。
本文的着重点将在于如何为模型准备数据,同时我还将讨论该模型的一些其他功能。我们将在此项目中使用Python 3和TensorFlow 1.1。数据是由古腾堡项目中的二十本流行书籍组成。如果你有兴趣扩大这个项目以使其更准确,那么你可以在古腾堡项目上下载数百本图书。此外,如果看到人们使用这种模式制作出的拼写检查器是多么的好用,那将是非常有趣的。
如果你想要查看完整的代码,可以在GitHub页面查看:https://github.com/Currie32/Spell-Checker
为了让你预览这个模型所具有的能力,这里有一些策划的例子可以当做参考:
Spellinis difficult,whchiswyhyou need to study everyday.
Spellingis difficult,whichiswhyyou need to study everyday.
The first days of her existence inthcountry werevreyhard for Dolly.
The first days of her existence inthecountry wereveryhard for Dolly.
Thiis really somethingimpressivthaatwe should look into right away!
Thisis really somethingimpressivethatwe should look into right away!
为了使事情更有条理,我把我们将使用的所有书籍放在他们自己的文件夹中,名称定为“books”。这是我们将用来加载所有书籍的函数:
def load_book(path):
input_file = os.path.join(path)
with open(input_file) as f:
book = f.read()
return book
同时,我们还需要为每本书定下一个唯一的文件名:
path = './books/'
book_files = [f for f in listdir(path) if isfile(join(path, f))]
book_files = book_files[1:]
当我们将这两个代码块放在一起时,我们将能够将所有书籍中的文本加载到列表中。
books = []
for book in book_files:
books.append(load_book(path+book))
如果你有兴趣了解每本书中有多少单词,你可以使用以下代码行:
for i in range(len(books)):
print("There are {} words in {}.".format(len(books[i].split()), book_files[i]))
注意:如果你的代码中不包括.split(),那么它将返回的是每本书中的字符数。
清理这些书的文本是相当简单的。由于我们将使用的是字符,而不是单词作为我们模型的输入,所以我们不需要担心去除停用词,或者将单词缩短到只留下主干。我们只需要删除我们不想要的字符和多余的空格。
def clean_text(text):
'''Remove unwanted characters and extra spaces from the text'''
text = re.sub(r'\n', ' ', text)
text = re.sub(r'[{}@_*>()\\#%+=\[\]]','', text)
text = re.sub('a0','', text)
text = re.sub('\'92t','\'t', text)
text = re.sub('\'92s','\'s', text)
text = re.sub('\'92m','\'m', text)
text = re.sub('\'92ll','\'ll', text)
text = re.sub('\'91','', text)
text = re.sub('\'92','', text)
text = re.sub('\'93','', text)
text = re.sub('\'94','', text)
text = re.sub('\.','. ', text)
text = re.sub('\!','! ', text)
text = re.sub('\?','? ', text)
text = re.sub(' +',' ', text) # Removes extra spaces
return text
我将跳过如何来制作vocab_to_int和int_to_vocab字典,因为这是非常标准的东西,你可以在这个项目的GitHub页面上找到它。但是,我认为值得向你展示输入数据中包含的字符:
The vocabulary contains 78 characters.
[' ', '!', '"', '$', '&', "'", ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<EOS>', '<GO>', '<PAD>', '?', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
我们可以删除更多的特殊字符,或者使文本全部小写,但是我想让这个拼写检查器尽可能有用。
数据在被输入到模型之前被组织成句子。我们将在每个时间段后跟一个空格(“.”)来拆分数据。一个问题是,一些句子是以问号或感叹号结尾的,但我们说话的时候不是这样的。幸运的是,我们的模型仍然能够理解使用问号和感叹号,只要与以下句子相结合,不超过最大句子长度。
举个例子来说明这个问题:
Today is a lovely day. I want to go to the beach. (这将被拆分为两个输入句子)
Is today a lovely day? I want to go to the beach. (这将是一个长的输入句子)
sentences = []
for book in clean_books:
for sentence in book.split('. '):
sentences.append(sentence + '.')
转载请注明出处。