web-dev-qa-db-fra.com

Modifier la distance en Python

Je programme un programme de vérification orthographique en Python. J'ai une liste de mots valides (le dictionnaire) et j'ai besoin de sortir une liste de mots de ce dictionnaire qui ont une distance d'édition de 2 à partir d'un mot invalide donné. 

Je sais que je dois commencer par générer une liste avec une distance de modification du mot invalide (puis l'exécuter à nouveau sur tous les mots générés). J'ai trois méthodes, insertions (...), suppressions (...) et modifications (...) qui doivent générer une liste de mots avec une distance d'édition de 1, où les insertions génèrent tous les mots valides avec une lettre de plus que le mot donné, suppressions, affiche tous les mots valides avec une lettre en moins, et les modifications affiche tous les mots valides avec une lettre différente.

J'ai vérifié plusieurs endroits mais je n'arrive pas à trouver un algorithme décrivant ce processus. Toutes les idées que j'ai suggérées impliquent de parcourir la liste de dictionnaires plusieurs fois, ce qui prendrait énormément de temps. Si quelqu'un pouvait offrir un aperçu, je vous en serais extrêmement reconnaissant.

23
Mel

La chose que vous regardez s'appelle une distance d'édition et voici une explication Nice sur wiki . Il existe de nombreuses façons de définir une distance entre les deux mots et celle que vous voulez s'appelle Levenshtein distance. Voici une implémentation DP en python.

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]

Et quelques autres implémentations sont ici .

42
Salvador Dali

Voici ma version pour la distance Levenshtein

 def edit_distance (s1, s2): 
 m = len (s1) +1 
 n = len (s2) +1 

 tbl = {} 
 pour i dans l'intervalle (m): tbl [i, 0] = i 
 pour j dans la plage (n): tbl [0, j] = j 
 pour i dans la plage (1, m): 
 pour j dans l'intervalle (1, n): 
 coût = 0 si s1 [i-1] == s2 [j-1] sinon 1 
 tbl [i, j] = min (tbl [i, j-1] +1, tbl [i-1, j] +1, tbl [i-1, j-1] + coût) 

 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]
7
ishaan arora

L'algorithme spécifique que vous décrivez s'appelle la distance de Levenshtein. Un rapide Google lance plusieurs bibliothèques et recettes Python pour le calculer.

1
Daniel Roseman

Vous avez besoin de Distance minimale d'édition pour cette tâche.

Voici ma version de 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

Au lieu d’utiliser Levenshtein distance, utilisez aussi BK tree ou TRIE, car ces algorithmes ont moins de complexité que la distance d’édition. Une bonne navigation sur ces sujets donnera une description détaillée.

Ce lien vous aidera davantage à propos de la vérification orthographique.

0
jt26