NLP之手動(dòng)搭建基礎(chǔ)單詞糾錯(cuò)器

1.導(dǎo)入詞庫(kù)

# 詞典庫(kù)
vocab = set([line.rstrip() for line in open('vocab.txt')])
print(vocab)

結(jié)果展示:

{'Rousseau', 'capsules', 'penetrated', 'predicting', 'unmeshed', 'Epstein', 'Eduardo', 'timetables', 'mahogany', 'catalog', 'Sodium', 'distortion', 'gilded', 'urinals', 'gagwriters', 'Fires', 'against', 'banner', 'Summerspace', 'apartment', 'conjure', '72.6', 'morticians', 'Goodis', 'distraction', 'Vikulov', 'brains', 'kidnapping', 'depraved', 'shock', 'pumping', 'fluxes', 'fecundity', 'pirate', 'willy', ',', 'Danchin', 'superlunary', 'Thurber', 'reminds', 'flattery', 'image', 'kernel', 'synthesize', 'Clint', 'Browne', 'Mahayana', 'sad', 'Len', 'screenings', 'dispenser', 'sustained', 'geographers', 'plug', 'succeeded', 'Falls', 'unkind', 'Severe', 'exploded', 'chronicle', 'honorably', 'fruit', 'lapped', 'rotate', 'crises', 'gentlemanly', 'revival', 'Alsing', 'members', 'synergistic', 'nakedly', 'singular', 'Flood', 'enzymatic', 'eyewitness', 'Premier', 'unsure', 'swarming', 'depot', 'survivals', 'Grace', 'anthropologists', 'Heretic', 'pastes', 'modifier', 'Catholics', 'some', 'pitcher'

2.生成所有候選集合

候選集合:一個(gè)正確單詞可能會(huì)出現(xiàn)的錯(cuò)誤輸入
編輯距離:一個(gè)字符串(錯(cuò)誤輸出)經(jīng)過(guò)幾次字母插入孵滞、刪除擎场、替換才能轉(zhuǎn)換成相應(yīng)的正確單詞。
注:下面代碼將采用編輯距離為1建立模型岔绸。即經(jīng)一個(gè)操作就能變成其他單詞兰伤。

# 需要生成所有候選集合
def generate_candidates(word):
    """
    word: 給定的輸入(錯(cuò)誤的輸入) 
    返回所有(valid)候選集合
    """
    """
    
    """
    # 生成編輯距離為1的單詞
    # 1.insert 2. delete 3. replace
    # appl: replace: bppl, cppl, aapl, abpl... 
    #       insert: bappl, cappl, abppl, acppl....
    #       delete: ppl, apl, app
    
    # 假設(shè)使用26個(gè)字符
    letters = 'abcdefghijklmnopqrstuvwxyz' 
    #splits所有可能的插入點(diǎn)信息找出來(lái),然后在不同位置進(jìn)行插入刪除替換
    #word[:i], word[i:]   從0到i-1行沛鸵,從i到最后一行,只有行就是第i個(gè)
    splits = [(word[:i], word[i:]) for i in range(len(word)+1)]
    # insert操作  L:左邊部分   c:插入的部分   R:右邊部分   LR來(lái)自splits中缆八,c來(lái)自letter中的每一個(gè)字符a-z
    inserts = [L+c+R for L, R in splits for c in letters]
    # delete   L加上R的從第二個(gè)字符開始  R部位空
    deletes = [L+R[1:] for L,R in splits if R]
    # replace   L加上c(從letter中截取的每一個(gè)字母)加上右邊的第二個(gè)字符到最后
    replaces = [L+c+R[1:] for L,R in splits if R for c in letters]
    
    candidates = set(inserts+deletes+replaces)
    
    # 過(guò)來(lái)掉不存在于詞典庫(kù)里面的單詞
    return [word for word in candidates if word in vocab] 
    
generate_candidates("apple")

結(jié)果展示:

['apple', 'ample', 'apply', 'apples']

3.讀取語(yǔ)料庫(kù)

from nltk.corpus import reuters

# 讀取語(yǔ)料庫(kù)
categories = reuters.categories()
corpus = reuters.sents(categories=categories)

格式展示:

raining: rainning, raning
writings: writtings
disparagingly: disparingly
yellow: yello

4.構(gòu)建語(yǔ)言模型

注:下面代碼的語(yǔ)言模型使用bigram曲掰,并且只考慮第i個(gè)單詞和第i+1個(gè)單詞的關(guān)系

# 構(gòu)建語(yǔ)言模型: bigram
term_count = {}
bigram_count = {}
for doc in corpus:
    doc = ['<s>'] + doc  #給第一個(gè)加一個(gè),這樣第一個(gè)單詞也會(huì)和前一個(gè)產(chǎn)生聯(lián)系,數(shù)據(jù)就會(huì)統(tǒng)一   trigrams應(yīng)該加兩個(gè)<s>
    for i in range(0, len(doc)-1):  #遍歷文章中的每一個(gè)詞
        # bigram: [i,i+1]
        term = doc[i] #第i個(gè)index里面的單詞
        bigram = doc[i:i+2]  # 第i個(gè)單詞和第i+1個(gè)單詞
        
        
        #統(tǒng)計(jì)信息
        if term in term_count:  #存在
            term_count[term]+=1
        else:
            term_count[term]=1  #第一次出現(xiàn)
        bigram = ' '.join(bigram)  
        if bigram in bigram_count:   #前后兩個(gè)單詞在一起的概率
            bigram_count[bigram]+=1
        else:
            bigram_count[bigram]=1

# sklearn里面有現(xiàn)成的包

5.根據(jù)數(shù)據(jù)奈辰,為每一個(gè)錯(cuò)誤輸入計(jì)算出現(xiàn)的概率

# 用戶打錯(cuò)的概率統(tǒng)計(jì) - channel probability
channel_prob = {}
#讀取正確的和錯(cuò)誤的
for line in open('spell-errors.txt'):
    items = line.split(":") 
    correct = items[0].strip()  
    mistakes = [item.strip() for item in items[1].strip().split(",")]
    channel_prob[correct] = {}
    for mis in mistakes:
        channel_prob[correct][mis] = 1.0/len(mistakes)

print(channel_prob) 

結(jié)果展示:

{'raining': {'rainning': 0.5, 'raning': 0.5}, 'writings': {'writtings': 1.0}, 'disparagingly': {'disparingly': 1.0}, 'yellow': {'yello': 1.0},

6.導(dǎo)入測(cè)試數(shù)據(jù)蜈缤,進(jìn)行拼寫糾錯(cuò)

數(shù)據(jù)格式:

1   1   They told Reuter correspondents in Asian capitals a U.S.  Move against Japan might boost protectionst sentiment in the  U.S. And lead to curbs on American imports of their products.

代碼實(shí)現(xiàn):

import numpy as np
V = len(term_count.keys())

file = open("testdata.txt", 'r')
for line in file:
    #一行三個(gè)元素  itmes[0]句子序號(hào)  itmes[1]句子中有幾個(gè)錯(cuò)誤單詞  itmes[2]句子
    items = line.rstrip().split('\t')
    line = items[2].split()
    # line = ["I", "like", "playing"]
    for word in line:
        if word not in vocab:
            # 需要替換word成正確的單詞
            # Step1: 生成所有的(valid)候選集合
            candidates = generate_candidates(word)
            
            # 一種方式: if candidate = [], 多生成幾個(gè)candidates, 比如生成編輯距離不大于2的
            # TODO : 根據(jù)條件生成更多的候選集合
            if len(candidates) < 1:
                continue   # 不建議這么做(這是不對(duì)的) 
            probs = []
            # 對(duì)于每一個(gè)candidate, 計(jì)算它的score
            # score = p(correct)*p(mistake|correct)
            #       = log p(correct) + log p(mistake|correct)
            # 返回score最大的candidate
            for candi in candidates:
                prob = 0
                # a. 計(jì)算channel probability
                if candi in channel_prob and word in channel_prob[candi]:
                    #之前計(jì)算好的概率
                    prob += np.log(channel_prob[candi][word])
                else:
                    prob += np.log(0.0001)
                
                # b. 計(jì)算語(yǔ)言模型的概率
                idx = items[2].index(word)+1
                # 這個(gè)biagrams是否存在于之前的語(yǔ)言模型  是:
                if items[2][idx - 1] in bigram_count and candi in bigram_count[items[2][idx - 1]]:
                    prob += np.log((bigram_count[items[2][idx - 1]][candi] + 1.0) / (
                            term_count[bigram_count[items[2][idx - 1]]] + V))
                # TODO: 也要考慮當(dāng)前 [word, post_word]
                #   prob += np.log(bigram概率)
                #否:賦予一個(gè)不為0但很小的值
                else:
                    prob += np.log(1.0 / V)

                probs.append(prob)
                
            max_idx = probs.index(max(probs))
            print (word, candidates[max_idx])

結(jié)果展示:由于沒(méi)有對(duì)句子中的標(biāo)點(diǎn)進(jìn)行過(guò)濾,有標(biāo)點(diǎn)的地方也當(dāng)成了拼寫錯(cuò)誤冯挎。

protectionst protectionist
products. products
long-run, long-run
gain. gain
17, 17e
retaiation retaliation
cost. cost
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末底哥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子房官,更是在濱河造成了極大的恐慌趾徽,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翰守,死亡現(xiàn)場(chǎng)離奇詭異孵奶,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蜡峰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門了袁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人湿颅,你說(shuō)我怎么就攤上這事载绿。” “怎么了油航?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵崭庸,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)怕享,這世上最難降的妖魔是什么执赡? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮函筋,結(jié)果婚禮上沙合,老公的妹妹穿的比我還像新娘。我一直安慰自己跌帐,他們只是感情好灌诅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著含末,像睡著了一般。 火紅的嫁衣襯著肌膚如雪即舌。 梳的紋絲不亂的頭發(fā)上佣盒,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音顽聂,去河邊找鬼肥惭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛紊搪,可吹牛的內(nèi)容都是我干的蜜葱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼耀石,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼牵囤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起滞伟,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤揭鳞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后梆奈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體野崇,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年亩钟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了乓梨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡清酥,死狀恐怖扶镀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情焰轻,我是刑警寧澤狈惫,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響胧谈,放射性物質(zhì)發(fā)生泄漏忆肾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一菱肖、第九天 我趴在偏房一處隱蔽的房頂上張望客冈。 院中可真熱鬧,春花似錦稳强、人聲如沸场仲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)渠缕。三九已至,卻和暖如春褒繁,著一層夾襖步出監(jiān)牢的瞬間亦鳞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工棒坏, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留燕差,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓坝冕,卻偏偏與公主長(zhǎng)得像徒探,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子喂窟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容