2010-08-10 37 views
6

Sorprendentemente, no he podido encontrar a nadie que realmente esté haciendo esto, pero seguramente alguien sí. Actualmente estoy trabajando en un proyecto de Python que implica la corrección ortográfica de unas 16 mil palabras. Esa cantidad de palabras solo va a crecer por desgracia. En este momento estoy sacando palabras de Mongo, iterando a través de ellas, y luego deletreo revisándolas con pyenchant. Eliminé a mongo como posible cuello de botella al agarrar todos mis artículos de allí primero. Eso me deja alrededor de 20 minutos para procesar 16k palabras, lo que obviamente es más largo de lo que quiero gastar. Esto me deja con un par de ideas/preguntas:Revisión ortográfica a "gran escala" en Python

  1. Obviamente, podría aprovechar el enhebrado o alguna forma de paralelismo. Incluso si corté esto en 4 pedazos, todavía estoy mirando aproximadamente 5 minutos que asumen funcionamiento máximo.

  2. ¿Hay alguna forma de saber qué biblioteca de ortografía Enchant usa debajo de pyenchant? El sitio web de Enchant parece implicar que utilizará todas las bibliotecas/diccionarios de ortografía disponibles cuando realice correcciones ortográficas. Si es así, entonces estoy potencialmente ejecutando cada palabra a través de tres a cuatro dictados de ortografía. Este podría ser mi problema aquí, pero estoy teniendo dificultades para demostrar que ese es el caso. Incluso si lo es, ¿es mi opción realmente desinstalar otras bibliotecas? Suena desafortunado

¿Alguna idea sobre cómo puedo sacar al menos un poco más el rendimiento de esto? Estoy de acuerdo con dividir esto en tareas paralelas, pero aún me gustaría conseguir que la pieza central sea un poco más rápida antes que yo.

Editar: Lo siento, publicar antes del café de la mañana ... Enchant genera una lista de sugerencias para mí si una palabra se deletrea incorrectamente. Eso parece ser donde paso la mayor parte de mi tiempo en esta parte de procesamiento.

+2

20 minutos por sólo 16 mil palabras suena como un tiempo terriblemente largo. ¿Podría simplemente cargar sus palabras en un diccionario de Python y hacer una búsqueda en cada una? Eso llevará ciertamente menos de 20 minutos. (Probablemente en menos de 20 minutos para escribir, también). – ggg

+1

¿Está utilizando todo el poder de Enchant, o simplemente está revisando si una palabra está escrita correctamente (es decir, en un diccionario previamente conocido)? Si es lo último, haz lo que dice 'ggg' y crea tu propio corrector ortográfico. – katrielalex

+2

Ni siquiera piense en paralelizar; Acabo de verificar 100k palabras contra un diccionario de 60k en menos tiempo de lo que tardé en presionar Enter. Necesitas un mejor algoritmo – msw

Respuesta

5

Creo que estamos de acuerdo en que el cuello de botella de rendimiento aquí es Encantar; para este tamaño de conjunto de datos, es casi instantáneo hacer un booleano isSpeltCorrectly. Así que, ¿por qué no:

  1. crear un conjunto en memoria de las palabras correctamente escritas-, usando los diccionarios que hace Encantar o ir a buscar su propio (por ejemplo OpenOffice's).

    Opcionalmente, uniquify las palabras del documento, digamos poniéndolas en un set. Esto probablemente no te ahorrará mucho.

  2. Compruebe si cada palabra está en el conjunto o no. Esto es rápido, porque es solo una búsqueda establecida. (Probablemente O(log N) donde N es el número de palabras? Asumiendo set cubos de hash y hace una búsqueda binaria ... un gurú Python me puede corregir aquí.)

  3. Si no es así, entonces piden a encantar recomendar una palabra para eso. Esto es necesariamente lento.

Esto supone que la mayoría de sus palabras están escritas correctamente; si no lo son, tendrás que ser más inteligente.

+0

Menos de 6 minutos yendo por esta ruta. Todavía es largo, pero es mejor. Solo bastantes errores de ortografía al rastrear la web :) – f4nt

+0

También podría intentar la paralelización de las búsquedas de Enchant, tal vez incluso con un proceso por separado que se ejecute como interfaz para encajar en el almacenamiento en caché. – katrielalex

+0

@ f4nt Estoy llegando a este problema también. ¿Qué usaste como fuente de palabras del diccionario? ¿Alguna otra información específica que puedas compartir sobre tu solución? – tw1742

1

Quizás una mejor forma de hacer esto sea comprimir el documento, ya que esto eliminaría cualquier instancia repetitiva de palabras, que en realidad solo necesita deletrear una vez. Solo sugiero esto, ya que probablemente sea más rápido que escribir tu buscador de palabras único.

La versión comprimida debe tener referencias a las palabras únicas, en algún lugar dentro de su archivo, puede que tenga que buscar cómo están estructuradas.

A continuación, puede corregir la ortografía de todas las palabras únicas. Espero que no los esté verificando con consultas SQL individuales o algo así, debería cargar un diccionario en forma de árbol en su memoria y luego verificar las palabras con eso.

Una vez hecho esto, simplemente descomprímalo y hey presto todo está corrector ortográfico. Esta debería ser una solución bastante rápida.

O tal vez no necesite realizar todo el proceso de compresión si la revisión ortográfica realmente es tan rápida como sugieren los comentarios, lo que indicaría una implementación incorrecta.

+0

Erm, no estoy seguro de entender. ¿Quieres decir comprimir el documento y analizar el archivo zip binario? ¿Estás seguro de que funciona? – katrielalex

+0

La única manera razonable de hacer que esto funcione sería hacer un árbol de Huffman donde los lexemas eran palabras enteras. Esto es computacionalmente equivalente a la respuesta de Katrielalex. Cualquier otra compresión que operara en el nivel de la sub-palabra sería increíblemente complicada pero no agregaría ninguna utilidad. – msw

2

Yo usaría un corrector ortográfico de estilo Peter Norvig. He escrito una publicación completa sobre esto.

http://blog.mattalcock.com/2012/12/5/python-spell-checker/

He aquí un fragmento del código que mira a posibles modificaciones de la palabra para comprobar.

def edits1(word): 
    s = [(word[:i], word[i:]) for i in range(len(word) + 1)] 
    deletes = [a + b[1:] for a, b in s if b] 
    transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b)>1] 
    replaces = [a + c + b[1:] for a, b in s for c in alphabet if b] 
    inserts = [a + c + b  for a, b in s for c in alphabet] 
    return set(deletes + transposes + replaces + inserts) 

Debería recorrer el creciente archivo de datos de las palabras para verificarlo extremadamente rápido con este código. Ver el post completo para obtener más información:

http://blog.mattalcock.com/2012/12/5/python-spell-checker/

Cuestiones relacionadas