Datos personales

Estudiante de la UNMSM - Facultad de Matemática - EAP Computación Cientifica

lunes, 25 de junio de 2012

Corrector Ortografico (Español) en Python


Empecemos conociendo un poco la parte teórica :


¿Cómo funciona?
Dada una palabra, estamos tratando de elegir la corrección ortográfica más probable para esa palabra(puede darse el caso en que la "corrección", sea la palabra original). No hay manera de saber con seguridad (ejemplo: "abarar" debe ser corregido por :"abarrar" o "abarraz"), lo que sugiere que usemos probabilidades. Vamos a decir que estamos tratando de encontrar la corrección C, de todas las correcciones posibles, tal corrección bebe tener la mayor probabilidad dada la palabra original W.
Max P(C|W) (1)

Usando el Teorema de Bayes, la expresión (1) es equivalente a :
Max P(C|W)= Max P(W|C)*P(C)/P(W) (2)


como P(w) es el mismo para todos los C posibles, se puede obviar, obteniendo de (2):
Max P(C|W)= Max P(W|C)*P(C) (3)

Entendamos a mayor detalle la expresión (3):

  • P(W), ¿cual es la probabilidad de que sea exactamente lo que se escribió?
  • P(C), dado un remplazo C, ¿cual es la probabilidad de que sea esa?, ejemplo: P ("la") tendría una probabilidad relativamente alta, mientras que P ("zxzxzxzyyy") sería cercano a cero.
  • P(W|C), ¿Cual es la probabilidad de que haya puesto W queriendo poner C?

Queremos la palabra C mas probable que se parezca a W

  • Si es muy distinta de W, C no nos sirve (ejem : W=berde, C=hola)
  • Si es muy rara, no nos sirve (ejem: W=verdo, C=bardo)
  • Si es común y parecida, C es genial (ejm: W=verda, C= verde)



Código Completo



#! /usr/bin/env python26
#-*- coding: utf-8 -*-
import re, collections

def words(text):
    """
    Escoje todas las palabras del text
    """
    return re.findall(u'[\xf1\xe1\xe9\xed\xf3\xfaa-z]+', unicode(text.lower(), 'utf-8'))


def train(features):
    """
   
calcula el P(C)
    """
    model = collections.defaultdict(lambda: 1)
    for f in features:
        model[f] += 1 
    list = []
    return model

NWORDS = train(words(file('DicEspaniol.txt').read()))
alphabet = u'abcdefghijklmnopqrstuvwxyz\xf1\xe1\xe9\xed\xf3\xfa'

def edits1(word):
 
    """
    Calcula el P(W/C) ----- distancia=1
    """
    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)


def known_edits2(word):
    """
        Calcula el P(W/C) ----- distancia=2 y se descarta si P(C)=0
    """
    return set(e2 for e1 in edits1(word) for
e2 in edits1(e1) if e2 in NWORDS)


def known(words):
    """
        Descarta si P(C)=0
    """
    return set(w for w in words if w in NWORDS)

def correct(word):
    """
    funcion principal
    """
    word = unicode(word.lower(), 'utf-8')
    candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word] 
    return max(candidates, key = NWORDS.get)
.encode('utf-8')

print correct("categoria")

5 comentarios:

  1. Sirve para corregir palabras que forman frases? o sea, por ejemplo, si quisiera corregir "correctorortográfico" se obtiene "corrector ortográfico"?, no se si me explico

    ResponderEliminar
    Respuestas
    1. No en realidad corrige solo una palabra, en el ejemplo que esta en el codigo : print correct("categoria") devuelve la palabra con tilde osea categoría.
      Este corrector depende mucho de 'DicEspaniol.txt' el cual debe contener una gran cantidad de palabra u oraciones en español.

      Eliminar
  2. hola soy nuesvo en python comenze ayer y me intereso bastante tu codigo pero no lo puedo ejecutar me salen errores y cosas por el estilo y en donde debo poner el DicEspañol.txt??? (aun soy un bebe en python :))

    agradeceria mucho tu ayuda

    ResponderEliminar
    Respuestas
    1. Hola el archivo DicEspañol.txt debe estar en el mismo lugar donde se encuentra tu archivo *.py. Ese archivo debe contener un gran número de palabras del Idioma Español. Y adelante con Python que es un lenguaje todo poderoso xD.

      Eliminar
  3. hola amigo esta buenísimo el post aunque tengo un problema, no me quiere mostrar las palabras con acentos y mucho menos la "ñ" en su lugar pone signos raros u.u (el archivo txt lo guarde en utf-8).

    de antemano muchas gracias.

    ResponderEliminar