Blog
Hunspell – Corrector Ortográfico en Python
- Publicado por: Rafael Fernandez
- Categoría: Blog

La librería Hunspell sirve de corrector ortográfico para Libreoffice, OpenOffice.org, Mozilla Firefox 3 & Thunderbird, Google Chrome, así como también es usado por paquetes de software privado como macOS, InDesing, memoQ, Opera y SDL Trados.
Esta librería tiene varias funcionalidades:
- Soporte extendido para las peculiaridades del lenguaje, codificación de caracteres Unicode, composición y morfología compleja
- Sugerencias mejoradas usando similitud con n-gramas.
- Análisis morfológico, derivación y generación.
- Posee interfaces para distintos lenguajes de programación, incluyendo Python
Hunspell le provee su funcionalidad a traves de la librería libhunspell a la cual podemos acceder desde Python a traves del módulo PyHunspell.
Descarga e instalación de Hunspell en Python
En distribuciones de linux puedes instalar la librería de Hunspell a traves de un administrador de paquetes como pip
.
pip install hunspell
También tenemos la opción de descargar el código fuente desde PyPI o el proyecto en GitHub y ejecutar el siguiente comando:
python setup.py install
Prerequisitos
Para usar esta librería necesitamos los paquetes python-dev
y libhunspell-dev
los cuales podemos instalar con el administrador de paquetes de nuestro (si estás en Linux) o con port/brew (Mac OSX). Luego tenemos que asegurarnos que tenemos los diccionarios instalados para el idioma que estaremos utilizando. También podemos hacer eso con nuestro administrador de paquetes, los paquetes tienen nombres como hunspell-en-us para inglés estadounidense, hunspell-es para español, etc.
Diccionarios
Usar la librería de Python es bastante sencillo. Primero necesitamos crear un objeto Hunspell, especificando las rutas a los diccionarios y anexando los archivos para nuestro idioma, por ejemplo, para el idioma español importamos el módulo y cargamos el diccionario:
import hunspell # Buscar diccionarios en carpeta de instalacion diccionario = hunspell.HunSpell('/usr/share/hunspell/es_ANY.dic', '/urr/share/hunspell/es_ANY.aff')
Cuando hayamos instalado los diccionarios con nuestro administrador de paquetes, estos archivos estarán localizados en /usr/share/hunspell. También podemos descargar los diccionarios en otra ubicación y especificarla cuando creemos el objeto Hunspell.
Ahora podemos utilizarlo verificando si una palabra esta en el diccionario:
>>> diccionario.spell('habitación') True >>> diccionario.spell('abitación') False
La palabra ‘england‘ no existe en el idioma español, lógicamente no se encuentra en el diccionario. Aún así podemos agregarla:
>>> diccionario.spell('england') False >>> diccionario.add('england') 0 >>> diccionario.spell('england') True
Así como podemos agregar palabras, también podemos eliminarlas:
>>> diccionario.spell('ejecutivo') True >>> diccionario.remove('ejecutivo') 0 >>> diccionario.spell('ejecutivo') False
Las funciones Hunspell.add
y Hunspell.remove
operan con el diccionario cargado en memoria. Todos los cambios no se guardan en realidad en el archivo del sistema.
Obtener sugerencias de una palabra
Usando el método Hunspell.suggest()
con una palabra podemos obtener sugerencias para esa palabra en el idioma del diccionario. Ejemplo:
>>> diccionario.suggest('abitación') ['habitación', 'agitación', 'habilitación', 'dubitación', 'citación', 'imitación'] >>> diccionario.suggest('ejecutivo') ['ejecutivo', 'ejecutivos', 'ejecutiva']
También podemos analizar morfológicamente y obtener el infinitivo de un verbo:
>>> diccionario.analyze('programé') [b' st:programar fl:R'] >>> diccionario.analyze('programas') [b' st:programa fl:S', b' st:programar fl:E']
Las funciones hunspell.analyze()
y hunspell.stem()
retornan strings en bytes, no en Unicode (por eso es que tienen la letra b de prefijo). Los bytes que retornan estas funciones son codificados en la codificación del diccionario y tenemos que decodificarlos manualmente para obtener strings apropiadas.
Usando Hunspell en un caso real
En esta sección crearemos una función que toma como argumentos un objeto Hunspell previamente creado, una lista de palabras y opcionalmente una lista de palabras aleatorias que deben ser agregadas primero al diccionario. La función retornará una lista de palabras corregidas.
import hunspell def corregir_palabras(corrector, palabras, agregarPrimero=[]): codificacion = corrector.get_dic_encoding() # obtenemos la codificacion para usarla luego # agregamos las palabras aleatorias al diccionario for palabra in agregarPrimero: corrector.add(palabra) # autocorreccion de palabras corregida = [] for p in palabras: ok = corrector.spell(p) # verificamos ortografia if not ok: sugerencias = corrector.suggest(p) if len(sugerencias) > 0: # hay sugerencias # tomamos la mejor sugerencia(decodificada a string) mejor_sugerencia = sugerencias[0] corregida.append(mejor_sugerencia) else: corregida.append(p) # no hay ninguna sugerecia para la palabra else: corregida.append(p) # esta palabra esta corregida return corregida if __name__ == '__main__': diccionario = hunspell.HunSpell('/usr/share/hunspell/es_ANY.dic', '/usr/share/hunspell/es_ANY.aff') palabras_aleatorias = ['casa', 'perro', 'carro'] palabras = ['program', 'python', 'piton', 'programador', 'progammer'] print('Se corrigieron las siguientes palabras: ') print(corregir_palabras(diccionario, palabras, palabras_aleatorias))
Resultado en consola:
Se corrigieron las siguientes palabras: ['programa', 'Marathon', 'pitón', 'programador', 'Gamero']
Veamos otro ejemplo en el que se crea una funcion que toma una lista de palabras y devuelve un diccionario con las palabras mal escritas como claves y una lista de sugerencias para esa palabra.
def lista_palabras_sugeridas(corrector, words, eco = True, agregarPrimero=[]): '''Toma una lista de palabras y devuelve un diccionario con las palabras mal escritas como claves y una lista de sugerencias para esa palabra''' # agrega palaba aleatoria al diccionario for w in agregarPrimero: corrector.add(w) sugerencias = {} for word in words: if isinstance(word, str): ok = corrector.spell(word) if not ok and word not in sugerencias: sugerencias[word] = corrector.suggest(word) if not sugerencias[word] and eco: print(word + ": Sin sugerencias") elif eco: print(word + ": " + "[", ", ".join(repr(i) for i in sugerencias[word]), "]")
Resultado en consola:
Sugerencias para las palabras entregadas: program: [ 'programa', 'programe', 'programo', 'programó', 'programá', 'programé' ] python: [ 'Marathon' ] piton: [ 'pitón', 'pito', 'pion', 'pinto', 'pitan', 'piten', 'pitos', 'pi ton', 'pi-ton' ] progammer: [ 'Gamero' ]