web-dev-qa-db-ja.com

Pythonで距離を編集

Pythonでスペルチェックプログラムをプログラミングしています。有効な単語のリスト(辞書)があり、この辞書から、指定された無効な単語との編集距離が2である単語のリストを出力する必要があります。

無効なWordから編集距離が1のリストを生成することから開始する必要があることを知っています(そして、生成されたすべての単語に対して再度実行します)。 inserts(...)、deletes(...)、changes(...)の3つのメソッドがあり、編集距離が1の単語のリストを出力する必要があります指定されたWordで、deletesはすべての有効な単語を1文字少なく出力し、changesはすべての有効な単語を1つの異なる文字で出力します。

たくさんの場所をチェックしましたが、このプロセスを説明するアルゴリズムを見つけることができないようです。私が思いついたすべてのアイデアは、辞書リストを複数回ループすることを伴いますが、これは非常に時間がかかります。誰かが洞察を提供できるなら、私は非常に感謝するでしょう。

34
Mel

あなたが見ているものは編集距離と呼ばれ、これは wikiの説明 です。 2つの単語間の距離を定義する方法はたくさんありますが、必要な単語はレーベンシュタイン距離と呼ばれ、PythonでのDP実装です。

def levenshteinDistance(s1, s2):
    if len(s1) > len(s2):
        s1, s2 = s2, s1

    distances = range(len(s1) + 1)
    for i2, c2 in enumerate(s2):
        distances_ = [i2+1]
        for i1, c1 in enumerate(s1):
            if c1 == c2:
                distances_.append(distances[i1])
            else:
                distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
        distances = distances_
    return distances[-1]

より多くの実装のカップルがここにあります

48
Salvador Dali

レーベンシュタイン距離の私のバージョンです

 def edit_distance(s1、s2):
 m = len(s1)+1 
 n = len(s2)+1 
 
 tbl = {} 
 range(m)のiの場合:tbl [i、0] = i 
 range(n)のjの場合:tbl [0、j] = j 
 for i in range(1、m):
 for j in range(1、n):
 cost = 0 if s1 [i-1] == s2 [j-1] else 1 
 tbl [i、j] = min(tbl [i、j-1] +1、tbl [i-1、j] +1、tbl [i-1、j-1] + cost)
 
 return tbl [i、j] 
 
 print(edit_distance( "Helloworld"、 "HalloWorld"))
10
Santosh
#this calculates edit distance not levenstein edit distance
Word1="rice"

Word2="ice"

len_1=len(Word1)

len_2=len(Word2)

x =[[0]*(len_2+1) for _ in range(len_1+1)]#the matrix whose last element ->edit distance

for i in range(0,len_1+1): #initialization of base case values

    x[i][0]=i
for j in range(0,len_2+1):

    x[0][j]=j
for i in range (1,len_1+1):

    for j in range(1,len_2+1):

        if Word1[i-1]==Word2[j-1]:
            x[i][j] = x[i-1][j-1] 

        else :
            x[i][j]= min(x[i][j-1],x[i-1][j],x[i-1][j-1])+1

print x[i][j]
8
ishaan arora

説明する特定のアルゴリズムは、レーベンシュタイン距離と呼ばれます。簡単なGoogleは、それを計算するためにいくつかのPythonライブラリとレシピをスローします。

2
Daniel Roseman

difflib 標準ライブラリには、get_close_matches使用できるメソッド。 RatcliffとObershelpから採用されたアルゴリズムを使用します。

ドキュメントから

from difflib import get_close_matches

# Yields ['Apple', 'ape']
get_close_matches('appel', ['ape', 'Apple', 'Peach', 'puppy'])
1
ryanjdillon

このタスクには最小編集距離が必要です。

以下は私のバージョンのMED a.k.a Levenshtein Distanceです。

def MED_character(str1,str2):
    cost=0
    len1=len(str1)
    len2=len(str2)

    #output the length of other string in case the length of any of the string is zero
    if len1==0:
        return len2
    if len2==0:
        return len1

    accumulator = [[0 for x in range(len2)] for y in range(len1)] #initializing a zero matrix

    # initializing the base cases
    for i in range(0,len1):
        accumulator[i][0] = i;
    for i in range(0,len2):
        accumulator[0][i] = i;

    # we take the accumulator and iterate through it row by row. 
    for i in range(1,len1):
        char1=str1[i]
        for j in range(1,len2):
            char2=str2[j]
            cost1=0
            if char1!=char2:
                cost1=2 #cost for substitution
            accumulator[i][j]=min(accumulator[i-1][j]+1, accumulator[i][j-1]+1, accumulator[i-1][j-1] + cost1 )

    cost=accumulator[len1-1][len2-1]
    return cost
1
Inaam Ilahi

レーベンシュタイン距離アルゴリズムを使用する代わりに、BK treeまたは[〜#〜] trie [〜#〜]、これらのアルゴリズムは編集距離よりも複雑さが少ないためです。これらのトピックを参照すると、詳細な説明が得られます。

この link は、スペルチェックの詳細に役立ちます。

0
jt26