當前位置:
首頁 > 科技 > NLP如何檢查拼寫錯誤?用Tensorflow,你也可以

NLP如何檢查拼寫錯誤?用Tensorflow,你也可以



NLP如何檢查拼寫錯誤?用Tensorflow,你也可以



本文編譯自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):


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"
", " ", 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) # 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", ":", ";", "", "", "


", "?", "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 + ".")


我在floydhub.com上使用GPU來訓練我的模型(我強烈推薦他們的服務),這節省了我幾個小時的訓練時間。儘管如此,為了正確調整這個模型,運行迭代仍然需要30-60分鐘的時間,這就是為什麼我要限制數據,從而不需要花費更長的時間來做這件事情。這當然會降低我們的模型的準確性,但由於這只是一個個人項目,所以,我不是很在乎。


max_length = 92


min_length = 10

good_sentences = []


for sentence in int_sentences:


if len(sentence) = min_length:


good_sentences.append(sentence)


為了跟蹤這個模型的性能,我將把數據拆分成一個訓練集和一個測試集。測試集將由數據15%的組成。


training, testing = train_test_split(good_sentences,


test_size = 0.15,


random_state = 2)


就像我最近的一些項目一樣,我將按照長度來給數據進行排序。這導致一批量的句子具有相似的長度,因此只需要使用較少的填充,並且模型將訓練的速度將更快。


training_sorted = []

testing_sorted = []


for i in range(min_length, max_length+1):


for sentence in training:


if len(sentence) == i:


training_sorted.append(sentence)


for sentence in testing:


if len(sentence) == i:


testing_sorted.append(sentence)


也許這個項目最有趣/最重要的部分就是將句子轉換為含有錯誤的句子的函數,這些函數將被用作輸入數據。在這個函數中創建的錯誤的方式將以下面三種之一的一種進行:


兩個字元的順序將被交換(hlelo?hello)

將添加一個額外的字母(heljlo?hello)


其中一個字元沒有被列印出來(helo?hello)


這三個錯誤發生的可能性是相等的,任一個錯誤發生的可能性為5%。因此,平均而言,每20個字元中就會有一個包含一個錯誤。


letters = ["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",]


def noise_maker(sentence, threshold):


noisy_sentence = []


i = 0


while i


if random


noisy_sentence.append(sentence[i])


else:


if new_random > 0.67:


if i == (len(sentence) - 1):


continue


else:


noisy_sentence.append(sentence[i+1])


noisy_sentence.append(sentence[i])


i += 1


elif new_random


noisy_sentence.append(vocab_to_int[random_letter])


noisy_sentence.append(sentence[i])


else:


pass


i += 1


return noisy_sentence


在本文中,我想向你展示的最後一件事是如何創建批次。通常,在訓練他們的模型之前,會先創建他們的輸入數據,這意味著他們具有固定數量的訓練數據。然而,當我們訓練我們的模型時,通過將noise_maker應用於每個批次,我們將要創建新的輸入數據。這意味著對於每個時期,目標(正確的)句子將通過noise_maker進行反饋,並應該接收一個新的輸入句子。使用這種方法的話,我們略微誇張地說,將會有無數量的訓練數據。


def get_batches(sentences, batch_size, threshold):


for batch_i in range(0, len(sentences)//batch_size):


start_i = batch_i * batch_size


sentences_batch = sentences[start_i:start_i + batch_size]


sentences_batch_noisy = []


for sentence in sentences_batch:


sentences_batch_noisy.append(


noise_maker(sentence, threshold))


sentences_batch_eos = []


for sentence in sentences_batch:


sentence.append(vocab_to_int[""])


sentences_batch_eos.append(sentence)


pad_sentences_batch = np.array(


pad_sentence_batch(sentences_batch_eos))


pad_sentences_noisy_batch = np.array(


pad_sentence_batch(sentences_batch_noisy))


pad_sentences_lengths = []


for sentence in pad_sentences_batch:


pad_sentences_lengths.append(len(sentence))


pad_sentences_noisy_lengths = []


for sentence in pad_sentences_noisy_batch:


pad_sentences_noisy_lengths.append(len(sentence))


yield (pad_sentences_noisy_batch,


pad_sentences_batch,


pad_sentences_noisy_lengths,


pad_sentences_lengths)


這就是整個這個項目!雖然結果是令人鼓舞的,但這種模式仍然存在著一定的局限性。我真的會很感激,如果有人可以擴大這個模型或改進其設計!如果你可以這樣做,請在評論中發表一下。新設計的想法將會應用到Facebook AI實驗室最新的CNN模型中去(它可以獲得最先進的翻譯結果)。


感謝你的閱讀,希望你可以從中學到新的知識!


來源:Towards Data Science


作者:Dave Currie

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器人圈 的精彩文章:

谷歌今天又開源了,這次是Sketch-RNN
深度對抗學習整裝待發,或將改變傳統AI格局
谷歌欲用FHIR進行精準醫療預測,「AI+醫療」時代踏步前進
Google重磅推出第二代TPU,即將進入雲
詳解谷歌AutoML演算法——神經網路是如何「自我升級」的?

TAG:機器人圈 |

您可能感興趣

如何解決 「mount.nfs:Stale file handle」錯誤
可能會利用Microsoft Edge錯誤將您的電子郵件泄露到惡意網站
Google 開源 ClusterFuzz:使得查找錯誤並修復錯誤變得異常簡單
幫你和錯誤say goodbye!
錯誤 could not launch process: EOF 解決
mybatis 查詢的時候提示 JDBC requiresJdbcType 錯誤
spring boot 整合shiro 錯誤
push to origin/master was rejected錯誤解決方案
扎克伯格:沒有禁止 Cambridge Analytica 的廣告是一個錯誤
殭屍毀滅工程steam is not enabled錯誤解決方法
英語 "get off on the wrong foot"從錯誤的一隻腳掉下來是什麼鬼
解決Electra越獄顯示Error:topanga錯誤的方法!
Electra 越獄 Cydia 出現紅黃字錯誤,原因看這裡
新版火狐瀏覽器錯誤導致Windows,Mac和Linux崩潰
同樣錯誤?!Dolce & Gabbana 推出賀年 T-Shirt 再被指「辱華」
解釋Electra工具上的Cydia整理插件源跳出錯誤提示!
Raf Simons的改造是個「錯誤」?Calvin Klein表現疲軟令母公司 PVH集團最新季度表現不及預期
為什麼economics翻譯為「經濟學」是個錯誤?
Win7解決werfault.exe應用程序錯誤方法
Give it to you是錯誤的表達!問題到底出在哪兒