Herramientas de usuario

Herramientas del sitio


materias:pln:2017:practico1

Trabajo Práctico 1 - Modelado de Lenguaje

(volver a la página principal)

En este trabajo práctico implementaremos varios modelos de lenguaje y realizaremos algunos experimentos con ellos.

Instrucciones

El código base para el proyecto se encuentra en el repositorio de la materia. La entrega del proyecto es a través de github. Por lo tanto, deben hacer un “fork” del repositorio dentro de sus cuentas de github.

Además del código fuente, deben elaborar un README con una breve explicación de lo que hicieron en cada ejercicio. El README puede estar en texto plano (txt), markdown (md) o restrucured text (rst), y debe estar incluído dentro de la carpeta languagemodeling.

Criterios de Evaluación:

  • Estilo de codificación (chequeado con flake8 y a ojo).
  • Diseño del código: uso de clases, herencia, etc.
  • Uso y aprobación de tests (provistos y definidos por uds.).
  • Uso apropiado de git (commits granulares, logs informativos).
  • Resultados.
  • README.

Ejercicio 1: Corpus

  • Elegir corpus de texto en lenguaje natural de más de 5Mb de tamaño.
  • Cargar el corpus usando un “corpus reader” de NLTK (e.g. PlaintextCorpusReader) o definiendo uno propio.
    • El “corpus reader” debe proveer un método sents que permita iterar sobre las oraciones tokenizadas del corpus.
  • Revisar a ojo la correcta tokenización y segmentado en oraciones. De ser necesario, probar otras formas de tokenización/segmentado.
  • Modificar el script train.py para utilizar nuestro corpus.

Documentación:

Ejercicio 2: Modelo de n-gramas

Implementar un modelo de n-gramas con marcadores de comienzo y fin de oración (<s> y </s>).

Interfaz de la clase NGram (en ngram.py):

class NGram:
 
    def __init__(self, n, sents):
        """
        n -- order of the model.
        sents -- list of sentences, each one being a list of tokens.
        """
 
    def count(self, tokens):
        """Count for an n-gram or (n-1)-gram.
 
        tokens -- the n-gram or (n-1)-gram tuple.
        """
 
    def cond_prob(self, token, prev_tokens=None):
        """Conditional probability of a token.
 
        token -- the token.
        prev_tokens -- the previous n-1 tokens (optional only if n = 1).
        """
 
    def sent_prob(self, sent):
        """Probability of a sentence. Warning: subject to underflow problems.
 
        sent -- the sentence as a list of tokens.
        """
 
    def sent_log_prob(self, sent):
        """Log-probability of a sentence.
 
        sent -- the sentence as a list of tokens.
        """

Tests:

$ nosetests languagemodeling/tests/test_ngram.py 

Ejercicio 3: Generación de Texto

  • Implementar en ngram.py una clase NGramGenerator para generar oraciones de lenguaje natural.
  • Programar un script generate.py para cargar un modelo de n-gramas y generar oraciones con él.
  • Generar oraciones usando n-gramas con n en {1, 2, 3, 4}. Armar una figura similar a la Figura 4.3 de Jurafsky & Martin (2008). Incluirla en el README.

Funciones a implementar en ngram.py:

class NGramGenerator:
 
    def __init__(self, model):
        """
        model -- n-gram model.
        """
 
    def generate_sent(self):
        """Randomly generate a sentence."""
 
    def generate_token(self, prev_tokens=None):
        """Randomly generate a token, given prev_tokens.
 
        prev_tokens -- the previous n-1 tokens (optional only if n = 1).
        """

Interfaz de generate.py:

$ python languagemodeling/scripts/generate.py  --help
Generate natural language sentences using a language model.

Usage:
  generate.py -i <file> -n <n>
  generate.py -h | --help

Options:
  -i <file>     Language model file.
  -n <n>        Number of sentences to generate.
  -h --help     Show this screen.

Tests:

$ nosetests languagemodeling/tests/test_ngram_generator.py 

Documentación:

Ejercicio 4: Suavizado "add-one"

  • Implementar el suavizado “add-one” en ngram.py en una clase AddOneNGram.
  • La clase debe tener la misma interfaz que NGram más el método V especificado abajo.
  • Calcular V como el tamaño del alfabeto incluyendo el marcador </s>.
  • Agregar al script de entrenamiento (train.py) una opción de línea de comandos que permita utilizar add-one en lugar de n-gramas clásicos.
  • Entrenar sobre nuestro corpus y guardar los modelos resultantes para varios valores de n (1, 2, 3 y 4).

Interfaz de la clase AddOneNGram (en ngram.py):

class AddOneNGram:
 
    """
       Todos los métodos de NGram.
    """
 
    def V(self):
        """Size of the vocabulary.
        """

Nueva interfaz de train.py:

$ python languagemodeling/scripts/train.py  --help
Train an n-gram model.

Usage:
  train.py -n <n> [-m <model>] -o <file>
  train.py -h | --help

Options:
  -n <n>        Order of the model.
  -m <model>    Model to use [default: ngram]:
                  ngram: Unsmoothed n-grams.
                  addone: N-grams with add-one smoothing.
  -o <file>     Output model file.
  -h --help     Show this screen.

Tests:

$ nosetests languagemodeling/tests/test_addone_ngram.py 

Ejercicio 5: Evaluación de Modelos de Lenguaje

  • Separar el corpus en entrenamiento y test (90% y 10% resp.).
  • Implementar el cálculo de log-probability, cross-entropy y perplejidad.
  • Programar un script eval.py para cargar un modelo de lenguajes y evaluarlo sobre el conjunto de test.
  • Calcular perplejidad de los modelos entrenados en el ejercicio anterior. Reportar los resultados en el README.

Interfaz de eval.py:

$ python languagemodeling/scripts/eval.py  --help
Evaulate a language model using the test set.

Usage:
  eval.py -i <file>
  eval.py -h | --help

Options:
  -i <file>     Language model file.
  -h --help     Show this screen.

Ejercicio 6: Suavizado por Interpolación

  • Implementar el suavizado por interpolación en ngram.py en una clase InterpolatedNGram.
  • Calcular lambdas en términos de un único parámetro gamma (ver documentación abajo).
  • Usar add-one para el nivel más bajo (unigramas).
  • Usar datos held-out (un 10% de train) y barrido para elegir valor para gamma.
  • Agregar al script de entrenamiento (train.py) una opción de línea de comandos que permita utilizar este modelo.
  • Calcular y reportar perplejidad para varios valores de n (1, 2, 3 y 4). Reportar los resultados en el README.

Interfaz de la clase InterpolatedNGram (en ngram.py):

class InterpolatedNGram:
 
    def __init__(self, n, sents, gamma=None, addone=True):
        """
        n -- order of the model.
        sents -- list of sentences, each one being a list of tokens.
        gamma -- interpolation hyper-parameter (if not given, estimate using
            held-out data).
        addone -- whether to use addone smoothing (default: True).
        """
 
    """
       Todos los métodos de NGram.
    """

Tests:

$ nosetests languagemodeling/tests/test_interpolated_ngram.py

Documentación:

Ejercicio 7: Suavizado por Back-Off con Discounting

  • Implementar el suavizado por back-off con discounting en ngram.py en una clase BackOffNGram.
  • Usar add-one para el nivel más bajo (unigramas).
  • Usar datos held-out (un 10% de train) y barrido para elegir valor para beta.
  • Agregar al script de entrenamiento (train.py) una opción de línea de comandos que permita utilizar este modelo.
  • Calcular y reportar perplejidad para varios valores de n (1, 2, 3 y 4). Reportar los resultados en el README.

Interfaz de la clase BackOffNGram (en ngram.py):

class BackOffNGram:
 
    def __init__(self, n, sents, beta=None, addone=True):
        """
        Back-off NGram model with discounting as described by Michael Collins.
 
        n -- order of the model.
        sents -- list of sentences, each one being a list of tokens.
        beta -- discounting hyper-parameter (if not given, estimate using
            held-out data).
        addone -- whether to use addone smoothing (default: True).
        """
 
    """
       Todos los métodos de NGram.
    """
 
    def A(self, tokens):
        """Set of words with counts > 0 for a k-gram with 0 < k < n.
 
        tokens -- the k-gram tuple.
        """
 
    def alpha(self, tokens):
        """Missing probability mass for a k-gram with 0 < k < n.
 
        tokens -- the k-gram tuple.
        """
 
    def denom(self, tokens):
        """Normalization factor for a k-gram with 0 < k < n.
 
        tokens -- the k-gram tuple.
        """

Tests:

$ nosetests languagemodeling/tests/test_backoff_ngram.py 

Documentación:

Ejercicio 8 (punto bonus): Reordenamiento de Palabras ó Atribución de Autoría

  • Elegir y resolver uno de los dos ejercicios siguientes de Jurafsky & Martin (2008):
    • Ejercicio 4.9: Reordenamiento de palabras.
    • Ejercicio 4.10: Atribución de autoría (Stylometry).
  • Sobre el ejercicio 4.9:
    • Implementar una clase que, dada una lista de palabras desordenadas de una oración, devuelva el ordenamiento más probable de acuerdo a un modelo de lenguaje.
    • Implementar un script que tome el conjunto de test y para cada oración, la desordene y la vuelva a ordenar usando un modelo de lenguaje dado como parámetro.
    • Usar las métricas BLEU y distancia de edición para evaluar la calidad de los reordenamientos (respecto de las oraciones originales). En NLTK:
      • nltk.metrics.distance.edit_distance
      • nltk.align.bleu_score.bleu
  • Sobre el ejercicio 4.10:
    • Se requiere tener documentos de dos o más clases diferentes. Por ejemplo, escritos de dos autores diferentes.
    • Definir conjuntos de entrenamiento y test para cada clase (90% y 10% resp.).
    • Entrenar un modelo de lenguaje para cada clase, siguiendo las indicaciones del libro.
    • Implementar un script que tome los conjuntos de test y adivine a qué clase corresponde cada uno.
materias/pln/2017/practico1.txt · Última modificación: 2019/02/05 19:42 por francolq