2011-12-15 18 views
12

Esto es algo en lo que estoy trabajando y me gustaría obtener información de las personas inteligentes aquí en StackOverflow.PHP Reparar el texto incorrecto

Lo que estoy intentando es una función para reparar texto basado en la combinación de varias versiones incorrectas de la misma página de texto. Básicamente, esto se puede utilizar para combinar diferentes resultados de OCR en uno con mayor precisión que cualquiera de ellos individualmente.

Empiezo con un diccionario de 600,000 palabras en inglés, eso es prácticamente todo, incluidos los términos legales y médicos y los nombres comunes. Ya tengo esto

Luego tengo 4 versiones de la muestra de texto.

Algo como esto:

$text[0] = 'Fir5t text sample is thisline'; 
$text[1] = 'Fir5t text Smplee is this line.'; 
$text[2] = 'First te*t sample i this l1ne.'; 
$text[3] = 'F i r st text s ample is this line.'; 

que intentar combinar lo anterior para obtener una salida que se parece a:

$text = 'First text sample is this line.'; 

No me digan que es imposible, porque no es, sin duda, solo muy dificil

Agradecería mucho cualquier idea que alguien tenga para esto.

¡Gracias!

Mis pensamientos actuales:

comprobando las palabras contra el diccionario no va a funcionar, ya que algunos de los espacios están en el lugar equivocado y en ocasiones la palabra no estarán en el diccionario.

La principal preocupación es la reparación de espaciamientos rotos, una vez que esto se soluciona, se puede elegir la palabra de diccionario más común, si existe, o la palabra que no aparece en el diccionario más común.

+2

¿realmente quieres combinar las 4 versiones con una, o es tu objetivo tomar una línea y arreglarla con la ayuda de tu diccionario? – Flo

+0

Puedo tomar fácilmente una línea y "revisar con ortografía" con el diccionario. Pero esto no ayudará ya que muchas de las palabras están rotas, los espacios están en lugares equivocados. Es por eso que necesito comparar las diferentes líneas, sí, combinarlas en una sola. – Alasdair

+0

De lo que estás hablando aquí suena mucho como un problema de Inteligencia Artificial. Podría ser posible en PHP, pero ciertamente no sería muy eficiente. Yo recomendaría buscar una herramienta de línea de comandos que hace que esto exista y que exista() desde PHP. Si tal herramienta no existe, entonces resolver el algoritmo sería una tarea increíble. Podrías comenzar revisando la ortografía de todas tus variantes y asumiendo que todas las palabras que son iguales en todas las versiones son correctas. Luego, para las líneas donde son diferentes, elija la palabra que aparece con más frecuencia. Después de eso, ¿quién sabe? – GordonM

Respuesta

1

Abordar algoritmos complejos como este por su cuenta probablemente llevará más tiempo y será más propenso a errores que usar una herramienta de terceros; a menos que realmente necesite programar esto usted mismo, puede verificar Yahoo Spelling Suggestion API. Permiten 5.000 solicitudes por IP por día, creo.

Otros pueden ofrecer algo similar (creo que también hay API de bing).

ACTUALIZACIÓN: Lo siento, acabo de leer que han detenido este servicio en abril de 2011. Afirman que ahora ofrecen un servicio similar llamado "Tabla YQL Sugerencia ortográfica".

1

Esto es de hecho un problema bastante complicado.

Cuando me pregunto cómo se deletrea una palabra, la manera directa es abrir un diccionario. Pero, ¿y si es una oración pequeña y compleja que estoy tratando de deletrear correctamente? Uno de mi truco personal, que funciona la mayor parte del tiempo, es llamar a Google. Coloco mi oración entre comillas en Google y cuento los resultados. Aquí hay un ejemplo: ingresar "muy inteligente" en Google da una página de 13'600k. Si ingresas "eres muy inteligente" obtendrás 20,000 páginas. Entonces, probablemente, la ortografía correcta es "eres muy inteligente". Y ... de hecho lo es;)

Basado en este concepto, supongo que tiene muestras que, en su mayor parte, están mal escritas correctamente (bueno, tal vez no si su desarrollo para un sitio de juegos para adolescentes ...) . ¿Puedes tratar de dividir las muestras en subunidades, sin subir las palabras, y unirlas por frecuencia?La pieza más frecuente es la más probable deletreada correctamente. Antes de esto, ya puede hacer un corrector ortográfico de diccionario con sus 600,000 términos para aumentar la posibilidad de que los pequeños errores de ortografía puedan corregirse. Esto debería aumentar la frecuencia de sub piezas correctas.

Dividir las oraciones en trozos y encontrar el "tamaño de pieza" correcto también es complicado.

Lo que me preocupa un poco también: ¿cómo extraer las muestras y unirlas para saber que la oración correctamente deletreada es la misma (o muy cercana?). Tu pregunta parece suponer que tienes esto, lo cual también parece ser algo muy complejo para mí.

Bueno, lo que precede es solo un consejo general basado en mi experiencia personal y humana. Donno si esto puede ayudar. Obviamente, esta no es una respuesta real y no está destinada a ser una.

1

Puede intentar usar Google n-grams para lograrlo.

+1

Se ve muy bien, pero no veo cómo podría ayudar? – Alasdair

1

Si necesita obtener la cadena correcta solo comparando otras. Entonces algo como esto quizás ayude.

Aún no ha terminado, pero ya da algunos resultados.

$text[0] = 'Fir5t text sample is thisline'; 
$text[1] = 'Fir5t text Smplee is this line.'; 
$text[2] = 'First te*t sample i this l1ne.'; 
$text[3] = 'F i r st text s ample is this line.'; 

function getRight($arr){ 
    $_final=''; 
    $count=count($arr); 

    // Remove multi spaces AND get string lengths 
    for($i=0;$i<$count;$i++){ 
     $arr[$i]=preg_replace('/\s\s+/', ' ',$arr[$i]); 
     $len[$i]=strlen($arr[$i]); 
    } 

    // Max length 
    $_max=max($len); 

    for($i=0;$i<$_max;$i++){ 
     $_el=array(); 
     for($j=0;$j<$count;$j++){ 
      // Cheking letter counts 
      $_letter=$arr[$j][$i]; 
      if(isset($_el[$_letter]))$_el[$_letter]++; 
      else$_el[$_letter]=1; 
     } 
     //Most probably count 
     list($mostProbably) = array_keys($_el, max($_el)); 

     $_final.=$mostProbably; 

     // If probbaly example is not space 
     if($_el!=' '){ 
      // THERE NEED TO BE CODE FOR REMOVING SPACE FROM LINES WHERE $text[$i] is space 
     } 
    } 

    return $_final; 
} 


echo getRight($text); 
+1

Usaría una distancia de Levenshtein ('levenshtein()' en PHP) en su caso :) – Minras

+0

¡Nunca he escuchado sobre esta función, thaks! Pero no sabemos qué palabra es "buena" para comparar. O entendí algo mal? – Narek

+0

Sí, tienes razón. Para la tarea de @ Alasdair sería demasiado costoso comparar cada palabra con el diccionario completo. Pero en tu caso, la distancia de Levenshtein es una buena solución. En cuanto al autor del tema, supongo que debería apegarse a las bibliotecas de ortografía existentes. – Minras

8

¿Ha intentado utilizar un algoritmo de subsecuencia común más larga? Estos se ven comúnmente en las herramientas de comparación de texto "diff" utilizadas en aplicaciones de control de código fuente y algunos editores de texto. Un algoritmo diff ayuda a identificar caracteres modificados y no modificados en dos ejemplos de texto. http://en.wikipedia.org/wiki/Diff

Hace algunos años trabajé en una aplicación de OCR similar a la suya. En lugar de aplicar múltiples motores de OCR a una imagen, utilicé un motor de OCR para analizar múltiples versiones de la misma imagen. Cada una de las imágenes procesadas fue el resultado de aplicar diferentes técnicas de eliminación de ruido a la imagen original: una técnica funcionaba mejor para el contraste bajo, otra técnica funcionaba mejor cuando los personajes estaban mal formados. Un esquema de "votación" que comparó los resultados de OCR en cada imagen mejoró la tasa de lectura para cadenas de texto arbitrarias como "BQCM10032". Otros esquemas de votación se describen en la literatura académica de OCR.

En ocasiones puede necesitar coincidir con una palabra para la cual ninguna combinación de resultados de OCR arrojará todas las letras. Por ejemplo, puede faltar una letra del medio, ya sea en "w rd" o "c tch" (probablemente "palabra" y "captura"). En este caso, puede ayudarlo a acceder a su diccionario con cualquiera de las tres teclas: letras iniciales, letras centrales y letras finales (o combinaciones de letras). Cada clave está asociada a una lista de palabras ordenadas por frecuencia de ocurrencia en el idioma. (Utilicé este tipo de búsqueda de varias teclas para mejorar la velocidad de una aplicación de generación de crucigramas; puede que haya mejores métodos, pero esta es fácil de implementar.)

Para ahorrar en memoria, puede aplicar el método multi-clave solo para las primeras miles de palabras comunes en el lenguaje, y luego solo tiene una técnica de búsqueda para palabras menos comunes.

Hay varias listas en línea de frecuencia de palabra. http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists

Si quiere ser elegante, también puede confiar en la frecuencia de ocurrencia previa en el texto. Por ejemplo, si "Byrd" aparece varias veces, entonces puede ser la mejor opción si el motor OCR informa "bird" o "bardo" con un bajo puntaje de confianza. Puede cargar un diccionario médico en la memoria solo si hay una ocurrencia estadísticamente improbable de términos médicos en la misma página; de lo contrario, deje los términos médicos fuera de su diccionario de trabajo, o al menos asígneles probabilidades razonables. "Prótesis" es una palabra común; "prostatitis" menos.

Si tiene experiencia con técnicas de procesamiento de imágenes tales como operaciones de eliminación de ruido y morfológicas, también puede intentar preprocesar la imagen antes de pasarla al motor (es) de OCR. El procesamiento de la imagen también podría aplicarse a áreas seleccionadas después de que su software identifique las palabras o regiones donde el (los) motor (es) de OCR tuvieron un mal rendimiento.

Ciertas sustituciones de letras/letras y letras/números son comunes. El número 0 (cero) se puede confundir con la letra O, C para O, 8 para B, E para F, P para R, y así sucesivamente. Si se encuentra una palabra con poca confianza, o si hay dos palabras comunes que podrían coincidir con una palabra incompletamente leída, entonces las reglas ad hoc de coincidencia de formas podrían ayudar. Por ejemplo, "bcth" podría coincidir con "ambos" o "baño", pero para muchas fuentes (y contextos) "ambos" es la coincidencia más probable ya que "o" es más similar a "c" en forma. En una larga cadena de palabras, como un párrafo de una novela o artículo de revista, "baño" es una mejor coincidencia que "b8".

Finalmente, es probable que pueda escribir un complemento o script para pasar los resultados a un motor de revisión ortográfica que verifica el acuerdo sustantivo-verbo y otras verificaciones gramaticales. Esto puede detectar algunos errores adicionales. Tal vez podrías probar VBA para Word o lo que sea que otro combo de secuencia de comandos/aplicaciones sea popular estos días.

+1

Ojalá todos los nuevos usuarios fueran como usted. +1 –

+0

¡Gracias! Lo aprecio. – Rethunk

Cuestiones relacionadas