En lingüística computacional y ciencias de la computación , la distancia de edición es una métrica de cadena , es decir, una forma de cuantificar cuán diferentes son dos cadenas (por ejemplo, palabras) entre sí, que se mide contando el número mínimo de operaciones necesarias para transformar una cadena en la otra. Las distancias de edición encuentran aplicaciones en el procesamiento del lenguaje natural , donde la corrección ortográfica automática puede determinar correcciones candidatas para una palabra mal escrita seleccionando palabras de un diccionario que tienen una distancia baja con la palabra en cuestión. En bioinformática , se puede utilizar para cuantificar la similitud de secuencias de ADN , que pueden verse como cadenas de las letras A, C, G y T.
Las distintas definiciones de distancia de edición utilizan distintos conjuntos de operaciones similares. Las operaciones de distancia de Levenshtein son la eliminación, inserción o sustitución de un carácter en la cadena. Al ser la métrica más común, el término distancia de Levenshtein suele usarse indistintamente con distancia de edición . [1]
Los distintos tipos de distancia de edición permiten distintos conjuntos de operaciones con cadenas. Por ejemplo:
Algunas distancias de edición se definen como una métrica parametrizable calculada con un conjunto específico de operaciones de edición permitidas, y a cada operación se le asigna un costo (posiblemente infinito). Esto se generaliza aún más mediante algoritmos de alineamiento de secuencias de ADN como el algoritmo Smith-Waterman , que hacen que el costo de una operación dependa de dónde se aplica.
Dadas dos cadenas a y b en un alfabeto Σ (por ejemplo, el conjunto de caracteres ASCII , el conjunto de bytes [0..255], etc.), la distancia de edición d( a , b ) es la serie de operaciones de edición de peso mínimo que transforma a en b . Uno de los conjuntos de operaciones de edición más simples es el definido por Levenshtein en 1966: [2]
En la definición original de Levenshtein, cada una de estas operaciones tiene un costo unitario (excepto que la sustitución de un carácter por sí mismo tiene un costo cero), por lo que la distancia de Levenshtein es igual al número mínimo de operaciones requeridas para transformar a en b . Una definición más general asocia las funciones de peso no negativas w ins ( x ), w del ( x ) y w sub ( x , y ) con las operaciones. [2]
Se han sugerido operaciones primitivas adicionales. La distancia de Damerau–Levenshtein cuenta como una edición única un error común: la transposición de dos caracteres adyacentes, formalmente caracterizado por una operación que cambia u x y v en u y x v . [3] [4] Para la tarea de corregir la salida de OCR , se han utilizado operaciones de fusión y división que reemplazan un solo carácter en un par de ellos o viceversa. [4]
Otras variantes de la distancia de edición se obtienen restringiendo el conjunto de operaciones. La distancia de subsecuencia común más larga (LCS) es la distancia de edición con inserción y eliminación como las únicas dos operaciones de edición, ambas con un costo unitario. [1] : 37 De manera similar, al permitir solo sustituciones (de nuevo con un costo unitario), se obtiene la distancia de Hamming ; esta debe restringirse a cadenas de igual longitud. [1] La distancia de Jaro-Winkler se puede obtener a partir de una distancia de edición donde solo se permiten transposiciones.
La distancia de Levenshtein entre "gatito" y "sentado" es 3. Un script de edición mínima que transforma el primero en el segundo es:
La distancia LCS (solo inserciones y eliminaciones) proporciona una distancia diferente y un script de edición mínimo:
por un coste total/distancia de 5 operaciones.
La distancia de edición con coste no negativo satisface los axiomas de una métrica , dando lugar a un espacio métrico de cadenas, cuando se cumplen las siguientes condiciones: [1] : 37
Con estas propiedades, los axiomas métricos se satisfacen como sigue:
La distancia de Levenshtein y la distancia LCS con costo unitario satisfacen las condiciones anteriores y, por lo tanto, los axiomas métricos. En la literatura también se han considerado variantes de la distancia de edición que no son métricas adecuadas. [1]
Otras propiedades útiles de las distancias de edición de costos unitarios incluyen:
Independientemente del costo/peso, la siguiente propiedad se cumple para todas las distancias de edición:
El primer algoritmo para calcular la distancia mínima de edición entre un par de cadenas fue publicado por Damerau en 1964. [6]
Usando las operaciones originales de Levenshtein, la distancia de edición (no simétrica) de a está dada por , definida por la recurrencia [2]
Este algoritmo se puede generalizar para manejar transposiciones agregando otro término en la minimización de la cláusula recursiva. [3]
La forma sencilla y recursiva de evaluar esta recurrencia requiere un tiempo exponencial . Por lo tanto, generalmente se calcula utilizando un algoritmo de programación dinámica que comúnmente se atribuye a Wagner y Fischer , [7] aunque tiene un historial de invención múltiple. [2] [3] Después de completar el algoritmo de Wagner-Fischer, se puede leer una secuencia mínima de operaciones de edición como un seguimiento inverso de las operaciones utilizadas durante el algoritmo de programación dinámica que comienza en .
Este algoritmo tiene una complejidad temporal de Θ( m n ) donde m y n son las longitudes de las cadenas. Cuando se construye la tabla de programación dinámica completa, su complejidad espacial también es Θ( m n ) ; esto se puede mejorar a Θ(min( m , n )) observando que en cualquier instante, el algoritmo solo requiere dos filas (o dos columnas) en la memoria. Sin embargo, esta optimización hace imposible leer la serie mínima de operaciones de edición. [3] El algoritmo de Hirschberg ofrece una solución de espacio lineal para este problema . [8] : 634 Chowdhury, Le y Ramachandran ofrecen un marco general recursivo de divide y vencerás para resolver tales recurrencias y extraer una secuencia óptima de operaciones de manera eficiente en caché en un espacio lineal en el tamaño de la entrada. [9]
Mejorando el algoritmo de Wagner-Fisher descrito anteriormente, Ukkonen describe varias variantes, [10] una de las cuales toma dos cadenas y una distancia máxima de edición s , y devuelve min( s , d ) . Esto se logra calculando y almacenando solo una parte de la tabla de programación dinámica alrededor de su diagonal. Este algoritmo toma tiempo O( s ×min( m , n )) , donde m y n son las longitudes de las cadenas. La complejidad espacial es O( s 2 ) o O( s ) , dependiendo de si la secuencia de edición necesita ser leída. [3]
Las mejoras posteriores de Landau , Myers y Schmidt [1] dan como resultado un algoritmo de tiempo O( s 2 + max( m , n )) . [11]
Para un alfabeto finito y costos de edición que son múltiplos entre sí, el algoritmo exacto más rápido conocido es el de Masek y Paterson [12], cuyo tiempo de ejecución en el peor de los casos es O(nm/logn).
La distancia de edición encuentra aplicaciones en biología computacional y procesamiento del lenguaje natural, por ejemplo, la corrección de errores ortográficos o de OCR, y la coincidencia aproximada de cadenas , donde el objetivo es encontrar coincidencias para cadenas cortas en muchos textos más largos, en situaciones en las que se espera una pequeña cantidad de diferencias.
Existen varios algoritmos que resuelven problemas además del cálculo de la distancia entre un par de cuerdas, para resolver tipos de problemas relacionados.
Una generalización de la distancia de edición entre cadenas es la distancia de edición del lenguaje entre una cadena y un lenguaje, normalmente un lenguaje formal . En lugar de considerar la distancia de edición entre una cadena y otra, la distancia de edición del lenguaje es la distancia de edición mínima que se puede alcanzar entre una cadena fija y cualquier cadena tomada de un conjunto de cadenas. Más formalmente, para cualquier lenguaje L y cadena x sobre un alfabeto Σ , la distancia de edición del lenguaje d( L , x ) está dada por [14] , donde es la distancia de edición de la cadena. Cuando el lenguaje L es libre de contexto , hay un algoritmo de programación dinámica de tiempo cúbico propuesto por Aho y Peterson en 1972 que calcula la distancia de edición del lenguaje. [15] Para familias de gramáticas menos expresivas, como las gramáticas regulares , existen algoritmos más rápidos para calcular la distancia de edición. [16]
La distancia de edición del lenguaje ha encontrado muchas aplicaciones diversas, como el plegamiento de ARN, la corrección de errores y las soluciones al problema de generación de pila óptima. [14] [17]