Text Mining: Distancia de Levenshtein La distancia de Levenshtein es un potente algoritmo que puede ser aplicado para tareas de Text Mining. Determina una medida de similaridad o cercanía entre dos cadenas de caracteres. Por ejemplo, la distancia de Levenshtein entre honda y onda es de 1, ya que se necesitan solo una edición elemental para cambiar uno en el otro: 1. honda onda (eliminación de h ) Este algoritmo fue propuesto por Vladimir Levenshtein en 1965 y desde entonces ha sido ampliamente usado para realizar el matching entre cadenas, por ejemplo, para correctores ortográficos. La implementación del algoritmo requiere el uso de una matriz de tamaño (n + 1) (m + 1), donde n y m son las longitudes de los cadenas que se comparan. Su implementación es sencilla, por ejemplo comparemos las palabras honda (para la cual n = 5) y onda (para la cual m = 4) Se acomodan en una matriz de (n, m) y se numeran como se muestra en la figura. o 1 n 2 d 3 a 4 La idea básica es comparar cada letra y asignar pesos, para ello si las letras son iguales el peso asignado es 0, sino el paso es 1, se toman los valores de la casilla de la izquierda, esquina superior izquierda y la casilla superior de las cuales se escoge el menor y se le suma el peso asignado. Por ejemplo para comparar la o y la h se consideran los pesos marcados de amarillo, el menor de ellos es 0 por lo tanto el valor nuevo de la casilla será 0 + 1 = 1, esta misma idea se hace con todas las otras casillas. La primera pasada quedaría: h 0 1 o 1 1 La segunda pasada: o 1 1 n 2 2 d 3 3 a 4 4 o 1 1 1 n 2 2 2 d 3 3 3 a 4 4 4 Aurelio López Ovando 1
Tercera pasada Cuarta pasada Quinta pasada h O n d a o 1 1 1 2 n 2 2 2 1 d 3 3 3 2 a 4 4 4 3 5 o 1 1 1 2 n 2 2 2 1 d 3 3 3 2 a 4 4 4 3 5 o 1 1 1 2 3 n 2 2 2 1 2 d 3 3 3 2 1 a 4 4 4 3 2 Sexta pasada Obtenemos la ruta mas corta 5 o 1 1 1 2 3 4 n 2 2 2 1 2 3 d 3 3 3 2 1 2 a 4 4 4 3 2 1 5 o 1 1 1 2 3 4 n 2 2 2 1 2 3 d 3 3 3 2 1 2 a 4 4 4 3 2 1 Concluimos que la distancia entre estas palabras es de 1, solo hay que hacer un cambio entre las palabras para que sean iguales. Este algoritmo es utilizado para comparar textos, existe una versión extendida que proporciona una mejor información en el parecido de las palabras utilizados por correctores ortográficos y buscadores en internet. Aurelio López Ovando 2
Distancia de Levenshtein en C# Creamos un nuevo proyecto al que llamamos DistanciaLevestein Creamos un formulario que nos muestre la información que queremos, como se muestra en la figura: Aurelio López Ovando 3
Agregamos una clase donde podamos desarrollar el algoritmo de la distancia de Levenshtein, la clase la llamaremos Levenstein. A la clase se le agrega el siguiente código como se muestra en el cuadro de texto siguiente: using System; using System.Collections.Generic; namespace DistanciaLevenstein class Levenstein public int LevenshteinDistance(string s, string t, out double porcentaje) porcentaje = 0; // d es una tabla con m+1 renglones y n+1 columnas int costo = 0; int m = s.length; int n = t.length; int[,] d = new int[m + 1, n + 1]; // Verifica que exista algo que comparar if (n == 0) return m; if (m == 0) return n; // Llena la primera columna y la primera fila. for (int i = 0; i <= m; d[i, 0] = i++) ; for (int j = 0; j <= n; d[0, j] = j++) ; /// recorre la matriz llenando cada unos de los pesos. /// i columnas, j renglones for (int i = 1; i <= m; i++) // recorre para j for (int j = 1; j <= n; j++) /// si son iguales en posiciones equidistantes el peso es 0 /// de lo contrario el peso suma a uno. costo = (s[i - 1] == t[j - 1])? 0 : 1; d[i, j] = System.Math.Min(System.Math.Min(d[i - 1, j] + 1, //Eliminacion d[i, j - 1] + 1), //Inserccion d[i - 1, j - 1] + costo); //Sustitucion /// Calculamos el porcentaje de cambios en la palabra. if (s.length > t.length) porcentaje = ((double)d[m, n] / (double)s.length); else porcentaje = ((double)d[m, n] / (double)t.length); return d[m, n]; Aurelio López Ovando 4
En el botón agregamos el siguiente código: private void btncalculadistancia_click(object sender, RoutedEventArgs e) Levenstein l = new Levenstein(); double h; int umbral = l.levenshteindistance(txpalabra1.text, txplabra2.text, out h); txumbral.text = umbral.tostring(); txpercent.text = h.tostring(); Obtenemos un resultados como se muestran a continuación: Entre mas se acerca al cero, las palabras son mas parecidas y entre mas elevado es el porcentaje indica que hay que hacer mas movimientos para que las palabras se parezcan, el porcentaje ayuda en el caso de que existan varias palabras muy parecidas, ese valor nos indica cual es la mas parecida. Aurelio López Ovando 5