tutorial - Seleccionar el texto más fluido de un conjunto de posibilidades a través de la verificación gramatical(Python)
tutorial django (4)
Algunos antecedentes
Soy un estudiante de literatura en New College of Florida, actualmente estoy trabajando en un proyecto creativo demasiado ambicioso. El proyecto está orientado hacia la generación algorítmica de poesía . Está escrito en Python. El conocimiento de My Python y el procesamiento del lenguaje natural provienen solo de enseñarme cosas a través de Internet. He estado trabajando con esto durante aproximadamente un año, así que no estoy indefenso, pero en varios momentos he tenido problemas para avanzar en este proyecto. Actualmente, estoy entrando en las fases finales de desarrollo y he topado con un pequeño obstáculo.
Necesito implementar alguna forma de normalización gramatical, para que la salida no salga como un lenguaje de hombre de las cavernas sin conjugar. Hace aproximadamente un mes algunos amigos de SO me dieron algunos consejos sobre cómo podría resolver este problema usando básicamente un modelador de lenguaje ngram , pero estoy buscando otras soluciones, ya que parece que el NgramModeler de NLTK no es apto para mis necesidades. (También se mencionaron las posibilidades del etiquetado POS, pero mi texto puede ser demasiado fragmentario y extraño para que una implementación de este sea fácil, dado mi nivel de aficionado).
Tal vez necesito algo como AtD, pero espero que sea menos complejo
Creo que necesito algo que funcione como After the Deadline o Queequeg , pero ninguno de estos parece exactamente correcto. Queequeg probablemente no sea una buena opción, fue escrito en 2003 para Unix y no puedo hacerlo funcionar en Windows por mi vida (lo he intentado todo). Pero me gusta que todo lo que verifique es la conjugación correcta de los verbos y el acuerdo numérico.
Por otro lado, AtD es mucho más riguroso y ofrece más capacidades de las que necesito. Pero parece que no puedo conseguir que los enlaces de python funcionen. (Recibo 502 errores del servidor AtD, que estoy seguro son fáciles de solucionar, pero mi aplicación va a estar en línea y prefiero evitar depender de otro servidor. No puedo permitirme ejecutar un servidor AtD yo mismo, porque la cantidad de "servicios" que mi aplicación requerirá de mi servidor web ya está amenazando con causar problemas para que esta aplicación sea alojada de forma económica).
Cosas que me gustaría evitar
La construcción de modelos de lenguaje de Ngram no me parece adecuada para la tarea. Mi aplicación arroja un montón de vocabulario desconocido, sesgando todos los resultados. (A menos que use un corpus que sea tan grande que funcione demasiado lento para mi aplicación, la aplicación debe ser bastante ágil).
La revisión estricta de la gramática no es adecuada para la tarea. la gramática no necesita ser perfecta, y las oraciones no tienen que ser más sensatas que el tipo de jilguero de tipo inglés que puedes generar usando ngrams. Incluso si es un jibberish, solo necesito forzar la conjugación de verbos, acuerdo de número, y hacer cosas como quitar artículos extra.
De hecho, ni siquiera necesito ningún tipo de sugerencias para las correcciones. Creo que todo lo que necesito es algo para calcular cuántos errores parecen ocurrir en cada oración en un grupo de oraciones posibles, para que pueda ordenar por su puntaje y elegir el que tenga menos problemas gramaticales.
¿Una solución simple? Puntuación de fluidez mediante la detección de errores obvios
Si existe una secuencia de comandos que se ocupa de todo esto, estaría encantado (todavía no he encontrado ninguno). Puedo escribir código para lo que no puedo encontrar, por supuesto; Estoy buscando consejos sobre cómo optimizar mi enfoque.
Digamos que tenemos un pequeño fragmento de texto ya presentado:
existing_text = "The old river"
Ahora digamos que mi script necesita descifrar qué inflexión del verbo "to bear" podría venir después. Estoy abierto a sugerencias sobre esta rutina. Pero necesito ayuda principalmente con el paso # 2 , calificando la fluidez al calcular los errores gramaticales:
- Use los métodos de Verb Conjugation en NodeBox Linguistics para llegar a todas las conjugaciones de este verbo;
[''bear'', ''bears'', ''bearing'', ''bore'', ''borne'']
. - Iterar sobre las posibilidades, (superficialmente) verificando la gramática de la cadena resultante de
existing_text + " " + possibility
("El oso del río viejo", "Los osos del río viejo", etc.). Sume el recuento de errores para cada construcción. En este caso, la única construcción para provocar un error, aparentemente, sería "El viejo oso del río". - Concluir debería ser fácil ... De las posibilidades con el conteo de errores más bajo, seleccione al azar.
Comprobación gramatical con enlace gramática
Introducción a la gramática de enlace
Link Grammar, desarrollado por Davy Temperley, Daniel Sleator y John Lafferty, es un analizador sintáctico del inglés: "Dada una oración, el sistema le asigna una estructura sintáctica, que consiste en un conjunto de enlaces etiquetados que conectan pares de palabras. parser también produce una representación "constituyente" de una oración (que muestra frases nominales, frases verbales, etc.) ". Puede leer más sobre Link Grammar e interactuar con un analizador en línea aquí .
Hace unos años AbiWord se hizo cargo del proyecto . Explican que AbiWord usa Link Grammar para verificar la gramática. No conozco las complejidades de cómo AbiWord de hecho realiza su revisión gramatical, pero leí sobre el enfoque básico en una sesión de preguntas y respuestas sobre la revisión gramatical (el enlace que ahora he perdido). A diferencia de otros analizadores con los que he interactuado, Link Grammar produce resultados muy diferentes cuando una oración no está bien formada gramaticalmente: no puede encontrar un vínculo completo para oraciones gramaticalmente inadecuadas .
Puede verlo por sí mismo con el analizador en línea : al ingresar la frase "Este es el hombre cuyo perro compré" produce 1 vínculo, mientras que "Este es el hombre cuyo perro compré" no produce vínculos completos.
Esto no "cuenta" el número de errores, como pedí. Sin embargo, cumple con el original como una forma de descartar posibilidades gramaticalmente inverosímiles (es decir, impropiamente conjugadas).
Enlaces de Python: ¡ellos existen!
Link Grammar está escrito en C. Esto me planteó un problema cuando estaba investigando por primera vez, ya que solo llevo un año estudiando la codificación de Python y sería muy difícil crear enlaces yo mismo. También me preocupaba mi cuenta de proceso / servicio, por lo que no quería ejecutar el programa Link Grammar sobre mi proceso de Python. Pero uno o dos días después de publicar esta pregunta el 13 de enero, me encontré con la contribución de pylinkgrammar de Jeff Elmore (pylinkgrammar) a PyPi, que ocurrió un día antes.
Como explica la página de pylinkgrammar , aún tienes que compilar e instalar linkgrammar primero. Las instrucciones sobre cómo usarlo están en esa página. Pero algunas precauciones sobre la instalación de pylinkgrammar:
- No pude obtener pylinkgrammar trabajando en Python 2.7 con Windows 7, lo que creo que se debe a problemas para que CMake funcione con Python 2.7 en Windows 7.
- Así que moví todo mi proyecto a Ubuntu (10.10), porque lo necesitaba tanto. Pero cuando configuré Ubuntu, intenté instalar todo para Python 2.7 (incluso eliminé 2.6). Todavía no podía hacer que pylinkgrammar trabajara con Python 2.7. Creo que esto todavía se debía a problemas entre CMake y Python 2.7.
- Comencé de nuevo con mi instalación de Ubuntu porque las cosas se habían complicado, y en su lugar configuré todo con Python 2.6. Ahora he conseguido pylinkgrammar trabajando con Python 2.6. (Pero tengo que escribir
from pylinkgrammar.linkgrammar import Parser
, que difiere ligeramente de las instrucciones de la página pypi).
NodeBox Linguistics: la otra parte de mi solución
En mi pregunta declaré la necesidad de generar todas las inflexiones / conjugaciones de una oración dada, para verificar todas estas variaciones y eliminar los elementos gramaticalmente inverosímiles. (Estoy usando WordNet para cambiar ciertas partes de las entradas de los usuarios antes de enviarlas, y los resultados de WordNet no están desvirtuados, necesitan inflexionarse para que las salidas (más) sean inteligibles).
Un blogpost muy informativo me llevó a la biblioteca NodeBox Linguistics , un conjunto de herramientas con las que "se puede inflexionar gramaticalmente y realizar operaciones semánticas sobre el contenido en inglés". De hecho, la biblioteca se puede usar para conjugar verbos, singularizar y pluralizar nombres, entre muchas otras operaciones. Esto es justo lo que necesitaba. Mi aplicación sabe qué palabras de una entrada ha cambiado para un nuevo idioma no flexionado; Estas piezas son para las que genera variaciones, utilizando los métodos de NodeBox Linguistics.
Alimento estas variaciones en variaciones de píxel y de goteo para las cuales no se pueden encontrar enlaces completos. A veces esto no produce resultados en absoluto, pero la mayoría de las veces produce resultados útiles. Tenga en cuenta que Link Grammar no encontrará enlaces completos para la mayoría de las oraciones incompletas. Si desea verificar las conjugaciones en oraciones fragmentadas como lo hago yo, intente extender las oraciones fragmentadas con relleno antes de marcarlas, luego suelte el relleno antes de emitir. Obtengo este "relleno" tomando la última palabra de los datos, buscándola en el corpus marrón y agregando el resto de esa oración del corpus.
No tengo ninguna prueba para informar sobre cuán preciso es este enfoque estadísticamente, pero ha funcionado para mis propósitos (peculiares) la mayor parte del tiempo. Todavía estoy en el proceso de desarrollar esta implementación y escribir casos excepcionales y formas de limpiar los datos de entrada. ¡Espero que esta información también ayude a alguien más! Por favor, no dude en pedir una aclaración.
El enlace pylinkgrammar proporcionado anteriormente está un poco desactualizado. Apunta a la versión 0.1.9, y los ejemplos de código para esa versión ya no funcionan. Si sigues este camino, asegúrate de usar la última versión que se puede encontrar en:
Otro enfoque sería utilizar lo que se llama un enfoque de sobregeneración y rango. En el primer paso, tu generador de poesía genera múltiples generaciones candidatas. Luego usa un servicio como el Turk''s Mechanical Turk de Amazon para recopilar juicios de fluidez humanos. De hecho, sugeriría recopilar juicios simultáneos para una serie de oraciones generadas a partir de las mismas condiciones de semilla. Por último, extrae características de las oraciones generadas (probablemente utilizando algún tipo de analizador sintáctico) para entrenar a un modelo para calificar o clasificar la calidad de las preguntas. Incluso podrías lanzar las heurísticas mencionadas anteriormente.
Michael Heilman usa este enfoque para la generación de preguntas. Para más detalles, lea estos documentos: ¡ Buena pregunta! Clasificación estadística para la generación de preguntas y la calificación de preguntas generadas por computadora con Mechanical Turk .
Un proyecto muy bueno, antes que nada.
Encontré un corrector de gramática de Java . Nunca lo he usado, pero los documentos afirman que puede ejecutarse como un servidor. Tanto Java como escuchar un puerto deberían ser compatibles básicamente en cualquier lugar.
Me estoy metiendo en PNL con un fondo CS, por lo que no me importaría entrar en más detalles para ayudarlo a integrar lo que decida usar. Siéntase libre de pedir más detalles.