0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

用21行python代碼實(shí)現(xiàn)的一個(gè)簡(jiǎn)易但是具備完整功能的拼寫檢查器

馬哥Linux運(yùn)維 ? 來(lái)源:未知 ? 作者:李倩 ? 2018-09-10 17:24 ? 次閱讀

引入

大家在使用谷歌或者百度搜索時(shí),輸入搜索內(nèi)容時(shí),谷歌總是能提供非常好的拼寫檢查,比如你輸入speling,谷歌會(huì)馬上返回spelling。

下面是用21行python代碼實(shí)現(xiàn)的一個(gè)簡(jiǎn)易但是具備完整功能的拼寫檢查器。

代碼

import re, collections

def words(text): return re.findall('[a-z]+', text.lower())

def train(features):

model = collections.defaultdict(lambda: 1)

for f in features:

model[f] += 1

return model

NWORDS = train(words(file('big.txt').read()))

alphabet = 'abcdefghijklmnopqrstuvwxyz'

def edits1(word):

splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]

deletes = [a + b[1:] for a, b in splits if b]

transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]

replaces = [a + c + b[1:] for a, b in splits for c in alphabet if b]

inserts = [a + c + b for a, b in splits for c in alphabet]

return set(deletes + transposes + replaces + inserts)

def known_edits2(word):

return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)

def known(words): return set(w for w in words if w in NWORDS)

def correct(word):

candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]

return max(candidates, key=NWORDS.get)

correct函數(shù)是程序的入口,傳進(jìn)去錯(cuò)誤拼寫的單詞會(huì)返回正確。如:

>>> correct("cpoy")

'copy'

>>> correct("engilsh")

'english'

>>> correct("sruprise")

'surprise'

除了這段代碼外,作為機(jī)器學(xué)習(xí)的一部分,肯定還應(yīng)該有大量的樣本數(shù)據(jù),準(zhǔn)備了big.txt作為我們的樣本數(shù)據(jù)。

背后原理

上面的代碼是基于貝葉斯來(lái)實(shí)現(xiàn)的,事實(shí)上谷歌百度實(shí)現(xiàn)的拼寫檢查也是通過(guò)貝葉斯實(shí)現(xiàn),不過(guò)肯定比這個(gè)復(fù)雜多了。

首先簡(jiǎn)單介紹一下背后的原理,如果讀者之前了解過(guò)了,可以跳過(guò)這段。

給一個(gè)詞,我們?cè)噲D選取一個(gè)最可能的正確的的拼寫建議(建議也可能就是輸入的單詞)。有時(shí)也不清楚(比如lates應(yīng)該被更正為late或者latest?),我們用概率決定把哪一個(gè)作為建議。我們從跟原始詞w相關(guān)的所有可能的正確拼寫中找到可能性最大的那個(gè)拼寫建議c:

argmaxc P(c|w)

通過(guò)貝葉斯定理,上式可以轉(zhuǎn)化為

argmaxc P(w|c) P(c) / P(w)

下面介紹一下上式中的含義:

P(c|w)代表在輸入單詞w 的情況下,你本來(lái)想輸入 單詞c的概率。

P(w|c)代表用戶想輸入單詞c卻輸入w的概率,這個(gè)可以我們認(rèn)為給定的。

P(c)代表在樣本數(shù)據(jù)中單詞c出現(xiàn)的概率

P(w)代表在樣本數(shù)字中單詞w出現(xiàn)的概率可以確定P(w)對(duì)于所有可能的單詞c概率都是一樣的,所以上式可以轉(zhuǎn)換為

argmaxc P(w|c) P(c)

我們所有的代碼都是基于這個(gè)公式來(lái)的,下面分析具體代碼實(shí)現(xiàn)

代碼分析

利用words()函數(shù)提取big.txt中的單詞

def words(text): return re.findall('[a-z]+', text.lower())

re.findall(‘[a-z]+’是利用python正則表達(dá)式模塊,提取所有的符合’[a-z]+’條件的,也就是由字母組成的單詞。(這里不詳細(xì)介紹正則表達(dá)式了,有興趣的同學(xué)可以看正則表達(dá)式簡(jiǎn)介。text.lower()是將文本轉(zhuǎn)化為小寫字母,也就是“the”和“The”一樣定義為同一個(gè)單詞。

利用train()函數(shù)計(jì)算每個(gè)單詞出現(xiàn)的次數(shù)然后訓(xùn)練出一個(gè)合適的模型

def train(features):

model = collections.defaultdict(lambda: 1)

for f in features:

model[f] += 1

return model

NWORDS = train(words(file('big.txt').read()))

這樣NWORDS[w]代表了單詞w在樣本中出現(xiàn)的次數(shù)。如果有一個(gè)單詞并沒(méi)有出現(xiàn)在我們的樣本中該怎么辦?處理方法是將他們的次數(shù)默認(rèn)設(shè)為1,這里通過(guò)collections模塊和lambda表達(dá)式實(shí)現(xiàn)。

collections.defaultdict()創(chuàng)建了一個(gè)默認(rèn)的字典,lambda:1將這個(gè)字典中的每個(gè)值都默認(rèn)設(shè)為1。(lambda表達(dá)式可以看lambda簡(jiǎn)介)

現(xiàn)在我們處理完了公式argmaxc P(w|c) P(c)中的P(c),接下來(lái)處理P(w|c)即想輸入單詞c卻錯(cuò)誤地輸入單詞w的概率,通過(guò) “edit distance“--將一個(gè)單詞變?yōu)榱硪粋€(gè)單詞所需要的編輯次數(shù)來(lái)衡量,一次edit可能是一次刪除,一個(gè)交換(兩個(gè)相鄰的字母),一次插入,一次修改。下面的函數(shù)返回一個(gè)將c進(jìn)行一次編輯所有可能得到的單詞w的集合:

def edits1(word):

splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]

deletes = [a + b[1:] for a, b in splits if b]

transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]

replaces = [a + c + b[1:] for a, b in splits for c in alphabet if b]

inserts = [a + c + b for a, b in splits for c in alphabet]

return set(deletes + transposes + replaces + inserts)

相關(guān)論文顯示,80-95%的拼寫錯(cuò)誤跟想要拼寫的單詞都只有1個(gè)編輯距離,如果覺(jué)得一次編輯不夠,那我們?cè)賮?lái)一次

def known_edits2(word):

return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)

同時(shí)還可能有編輯距離為0次的即本身就拼寫正確的:

def known(words):

return set(w for w in words if w in NWORDS)

我們假設(shè)編輯距離1次的概率遠(yuǎn)大于2次的,0次的遠(yuǎn)大于1次的。下面通過(guò)correct函數(shù)先選擇編輯距離最小的單詞,其對(duì)應(yīng)的P(w|c)就會(huì)越大,作為候選單詞,再選擇P(c)最大的那個(gè)單詞作為拼寫建議

def correct(word):

candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]

return max(candidates, key=NWORDS.get)

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4671

    瀏覽量

    67770
  • 貝葉斯
    +關(guān)注

    關(guān)注

    0

    文章

    77

    瀏覽量

    12531
  • python
    +關(guān)注

    關(guān)注

    53

    文章

    4753

    瀏覽量

    84081

原文標(biāo)題:python實(shí)現(xiàn)拼寫檢查器21行輕松搞定

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    分享50條經(jīng)典的Python一行代碼

    今天浩道跟大家分享python學(xué)習(xí)過(guò)程中非常經(jīng)典的50條一行代碼,讓大家體驗(yàn)它簡(jiǎn)潔而功能強(qiáng)大的特點(diǎn)。同時(shí)給大家分享號(hào)主收集到的所有關(guān)于python
    發(fā)表于 08-16 15:00 ?879次閱讀

    python編寫個(gè)高效搜索代碼工具

    python編寫個(gè)高效搜索代碼工具大多碼農(nóng)在linux環(huán)境下使用grep+關(guān)鍵詞的命令搜索自己想要的
    發(fā)表于 01-16 15:24

    數(shù)據(jù)分析為什么Python?只需4代碼就可以畫地圖

    Python 4代碼即可以畫出個(gè)地圖,8
    的頭像 發(fā)表于 05-28 16:16 ?4890次閱讀
    數(shù)據(jù)分析為什么<b class='flag-5'>用</b><b class='flag-5'>Python</b>?只需4<b class='flag-5'>代碼</b>就可以畫地圖

    如何實(shí)現(xiàn)計(jì)算機(jī)視覺(jué)的目標(biāo)檢測(cè)10Python代碼幫你實(shí)現(xiàn)

    只需10Python代碼,我們就能實(shí)現(xiàn)計(jì)算機(jī)視覺(jué)中目標(biāo)檢測(cè)。 沒(méi)錯(cuò),這寥寥10
    的頭像 發(fā)表于 02-03 11:35 ?2977次閱讀

    如何使用50Python代碼實(shí)現(xiàn)AI的動(dòng)作平衡

    本文將為大家展示如何通過(guò) Numpy 庫(kù)和 50 Python 代碼,使用標(biāo)準(zhǔn)的 OpenAI Gym平臺(tái)創(chuàng)建智能體 (agent),就教會(huì)機(jī)器處理推車桿問(wèn)題 (cart pole problem) ,保持平衡。
    的頭像 發(fā)表于 06-16 10:40 ?3044次閱讀

    盤點(diǎn)10個(gè)一行強(qiáng)大的、有趣的Python代碼

    Python門非常簡(jiǎn)潔而優(yōu)美的編程語(yǔ)言,在其他編程語(yǔ)言中需要繁瑣的代碼邏輯才能完成的事情,往往在Python一行就可以解決。
    的頭像 發(fā)表于 10-08 14:33 ?8657次閱讀

    使用Python讀文件的源代碼免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用Python讀文件的源代碼免費(fèi)下載。
    發(fā)表于 10-22 17:57 ?12次下載
    使用<b class='flag-5'>Python</b>按<b class='flag-5'>行</b>讀文件的源<b class='flag-5'>代碼</b>免費(fèi)下載

    Python代碼的性能分析的命令合集

    。注意,在本教程中,我建議使用 Anaconda。1.分析一行代碼檢查一行 python 代碼
    發(fā)表于 11-25 10:43 ?10次下載

    python設(shè)計(jì)個(gè)簡(jiǎn)單推薦系統(tǒng)的資料和完整代碼

    本文檔的主要內(nèi)容詳細(xì)介紹的是python設(shè)計(jì)個(gè)簡(jiǎn)單推薦系統(tǒng)的資料和完整代碼免費(fèi)下載。
    發(fā)表于 03-30 09:32 ?14次下載

    淺析FPGA開(kāi)發(fā)-Sublime編輯

    Sublime Text 是個(gè)文本編輯(收費(fèi)軟件,可以無(wú)限期試用,但是會(huì)有激活提示彈窗),同時(shí)也是
    的頭像 發(fā)表于 11-09 09:14 ?1991次閱讀
    淺析FPGA開(kāi)發(fā)-Sublime編輯<b class='flag-5'>器</b>

    3代碼實(shí)現(xiàn)單片機(jī)Uart功能

    文章目錄前言、實(shí)現(xiàn)功能二、接線圖三、完整代碼前言shineblink core 開(kāi)發(fā)板(簡(jiǎn)稱Core)的庫(kù)函數(shù)支持GPIO讀寫
    發(fā)表于 12-28 19:27 ?1次下載
    3<b class='flag-5'>行</b><b class='flag-5'>代碼</b><b class='flag-5'>實(shí)現(xiàn)</b>單片機(jī)Uart<b class='flag-5'>功能</b>

    3代碼一個(gè)WebServer

    電子發(fā)燒友網(wǎng)站提供《3代碼一個(gè)WebServer.zip》資料免費(fèi)下載
    發(fā)表于 10-28 16:52 ?0次下載
    <b class='flag-5'>用</b>3<b class='flag-5'>行</b><b class='flag-5'>代碼</b>做<b class='flag-5'>一個(gè)</b>WebServer

    20個(gè)非常有用的Python單行代碼

    有用的 Python 單行代碼片段,只需一行代碼即可解決特定編碼問(wèn)題!
    的頭像 發(fā)表于 03-14 17:45 ?800次閱讀

    一行代碼Python程序轉(zhuǎn)換為GUI應(yīng)用程序

    Gooey項(xiàng)目支持一行代碼將(幾乎)任何Python 2或3控制臺(tái)程序轉(zhuǎn)換為GUI應(yīng)用程序。 1.快速開(kāi)始 開(kāi)始之前,你要確保Python
    的頭像 發(fā)表于 10-17 11:41 ?790次閱讀
    <b class='flag-5'>一行</b><b class='flag-5'>代碼</b>將<b class='flag-5'>Python</b>程序轉(zhuǎn)換為GUI應(yīng)用程序

    一行代碼Python程序轉(zhuǎn)換為圖形界面應(yīng)用

    Gooey項(xiàng)目支持一行代碼將(幾乎)任何Python 2或3控制臺(tái)程序轉(zhuǎn)換為GUI應(yīng)用程序。 1.快速開(kāi)始 開(kāi)始之前,你要確保Python
    的頭像 發(fā)表于 10-30 15:39 ?379次閱讀
    <b class='flag-5'>一行</b><b class='flag-5'>代碼</b>將<b class='flag-5'>Python</b>程序轉(zhuǎn)換為圖形界面應(yīng)用