を使用して自動修正


デジタル化のこの時代に、ほとんどすべての個人は、彼らとスマートフォンを持っています.スマートフォンの利点は終わらないリストであり、我々はこのブログでは、それに集中するつもりはない!この投稿の目的は、タイトル自体からそれを推測できるように、ゼロから自動修正システムを構築することです.はい、それは間違いなく、正確にコピーされていない場合は、現在使用しているスマートフォンのそれには似ていますが、これは単なる比較的小さなデータセットで自然言語処理の実装になります-シェークスピア.TXT(彼の作品のウィリアムシェイクスピアによって使用される単語のファイル).
このアルゴリズムは、彼のarticleで2007年にピーターNorvigによって最初につくられました.

問題の概要
このモデルでは,語彙を含むリスト内の単語対の編集距離を考慮する.基本的に、編集距離は、1つの単語を別の単語に変換するために必要な最小限の編集の尺度です.
変換のこのプロセスには、削除、置換、スイッチ、および単語のペアに挿入のような手順が含まれます.このブログでは、複雑さを減らすために、1または2の距離を編集している単語を行きます.
右の出力を生成する私たちのモデルの目標は、正しい単語の確率を計算することです、P(c/w)は、正しいと仮定された特定の単語wの確率は、p(w/c)、一般的に正しいことの確率に乗算され、p(c)、その単語の確率、p(w)によって分割された.
フォーミュラ𝑃(𝑐|𝑤)=𝑃(𝑤|𝑐)×𝑃(𝑐)/𝑃(𝑤)
この方法をベイズ定理と呼ぶ.

そして、我々はすべての前に旅のために設定されています!
必要なパッケージをインポートします
import re
from collections import Counter
import numpy as np
import pandas as pd
データの前処理
def process_data(file_name):
    words = [] 
    with open(file_name) as f:
        file_name_data = f.read()
    file_name_data=file_name_data.lower()
    words = re.findall(r'\w+',file_name_data)

    return words

word_l = process_data('shakespeare.txt')
vocab = set(word_l)
ここでは、ファイルを取る関数プロセスデータを使用します
シェークスピア.入力としてTXTは、単語、リスト内のすべての単語のリストを無視して数値を無視し、すべての単語を小文字に変換します.再び、我々はWordCore Lによって受信された単語のリストからすべての単語のセットとして、テキストファイル、語彙の語彙を設定します.
今、私たちは入力ファイルから単語のリストの語彙とその出現数のカウント辞書を作成します.
def get_count(word_l):
    word_count_dict = {}  # fill this with word counts
    word_count_dict = Counter(word_l)
    return word_count_dict

word_count_dict = get_count(word_l)
上記の関数は、単語をキーとなり、それぞれの単語に割り当てられた値は単語の単語のリストに表示されている回数です.
次に、キーとしてすべての単語を含む辞書が必要になり、各キーに割り当てられた値が入力ファイルシェークスピアの特定の単語(キー)の発生の確率になります.txt.
def get_probs(word_count_dict):
    probs = {}  # return this variable correctly

    m = sum(word_count_dict.values())
    for key in word_count_dict :
        probs[key] = word_count_dict[key]/m
    return probs

probs = get_probs(word_count_dict)
Propsは、それぞれの単語wとそれぞれの確率p(w)を含む必要な辞書です.
さて、ここで私たちのモデルの最も重要な側面が来る!次のコードスニペットでは、タスクを実行する機能を実装する予定です.削除、スイッチ、置換、挿入し、各タスクからの単語のそれぞれのリストを返します.
def delete_letter(word):
    delete_l = []
    split_l = []

    for i in range(len(word)):
        split_l.append([word[:i],word[i:]])
    for a,b in split_l :
        delete_l.append(a+b[1:])

    return delete_l
def switch_letter(word):
    switch_l = []
    split_l = []

    for c in range(len(word)):
        split_l.append([word[:c],word[c:]])
    switch_l = [a + b[1] + b[0] + b[2:] for a,b in split_l if len(b) >= 2]    

    return switch_l
def replace_letter(word):
    letters = 'abcdefghijklmnopqrstuvwxyz'
    replace_l = []
    split_l = []

    for c in range(len(word)):
        split_l.append((word[0:c],word[c:]))
    replace_l = [a + l + (b[1:] if len(b)> 1 else '') for a,b in split_l if b for l in letters]
    replace_set=set(replace_l)    
    replace_set.remove(word)
    # turn the set back into a list and sort it, for easier viewing
    replace_l = sorted(list(replace_set))

    return replace_l
def insert_letter(word):
    letters = 'abcdefghijklmnopqrstuvwxyz'
    insert_l = []
    split_l = []

    for c in range(len(word)+1):
        split_l.append((word[0:c],word[c:]))
    insert_l = [ a + l + b for a,b in split_l for l in letters]

    return insert_l
上記の関数は、特定の種類のエディットの単語リストを生成します.我々は、N = 1 , 2だけを使用するN - Edit距離アルゴリズムを使用することによって、ファイルから入力語のリストの各単語のために全体としてこれらを使用する必要があります.
そこで、一度に一つの文字を編集したいなら、N = 1を選び、以下の関数を実装します:
def edit_one_letter(word, allow_switches = True):
    edit_one_set = set()

    edit_one_set.update(delete_letter(word))
    if allow_switches:
        edit_one_set.update(switch_letter(word))
    edit_one_set.update(replace_letter(word))
    edit_one_set.update(insert_letter(word))

    return edit_one_set
同様に、私たちが一度に2つの手紙を編集するのを選ぶならば、我々はN = 2のために行きます、そして、語の我々のリストの上で以下の機能を実行します.そして、それは2回、上記の機能を使用するつもりです.
def edit_two_letters(word, allow_switches = True):
    edit_two_set = set()

    edit_one = edit_one_letter(word,allow_switches=allow_switches)
    for w in edit_one:
        if w:
            edit_two = edit_one_letter(w,allow_switches=allow_switches)
            edit_two_set.update(edit_two)

    return edit_two_set
最後に、与えられた関数にEditSum TwoRank Letters ()とEditChoreOneRenletter ()を使用して、NHERN BESTという名前のリストのそれぞれの確率とともに、すべての候補のリストを取得します.
def get_corrections(word, probs, vocab, n=2):    
    suggestions = []
    n_best = []

    suggestions = list((word in vocab and word) or edit_one_letter(word).intersection(vocab) or edit_two_letters(word).intersection(vocab))
    n_best = [[s,probs[s]] for s in list(reversed(suggestions))]

    return n_best
ここで、提案にはvotabやedittle onepersletter ()とvoabやeditSense Twoanger letter ()とvoabから得られた単語のリストの間の共通語があります.
それは見ることができるように、ナースベストは正しいことのそれぞれの確率を持つすべての提案された単語のリストを返します.

モデルのテスト
次のコードスニペットを使用してAuto正しいモデルをテストします.
my_word = 'dys' 
tmp_corrections = get_corrections(my_word, probs, vocab, 2) 
for i, word_prob in enumerate(tmp_corrections):
    print(f"word {i}: {word_prob[0]}, probability {word_prob[1]:.6f}")
得られた結果は0 . 000019の確率の染料と0 . 0410の確率の日であった.

それはすべての人々です!
これは、自然言語処理とPythonを使用して独自の自動修正モデルを作成する方法です.
あなたの貴重な時間と忍耐に感謝!