Tabla de Contenidos
Trabajo Práctico 1 - Modelado de Lenguaje
(volver a la página principal)
En este trabajo práctico implementaremos modelos de lenguaje y realizaremos algunos experimentos con ellos.
- Repositorio: https://github.com/PLN-FaMAF/PLN-UBA2018.
- Fecha de entrega:
15/0218/02 a las 23:59.
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 tokenización y segmentado en oraciones. Si es muy mala, probar otras formas de tokenización/segmentado.
- Modificar el script
train.py
para utilizar el nuevo 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
Documentación:
Ejercicio 3: Generación de Texto
- Implementar en
ngram_generator.py
una claseNGramGenerator
para generar oraciones de lenguaje natural. - Usar el 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_generator.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 claseAddOneNGram
. - La clase debe tener la misma interfaz que
NGram
más el métodoV
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.
Interfaz de la clase AddOneNGram
(en ngram.py
):
class AddOneNGram: """ Todos los métodos de NGram. """ def V(self): """Size of the vocabulary. """
Tests:
$ nosetests languagemodeling/tests/test_addone_ngram.py
Documentación:
Ejercicio 5: Evaluación de Modelos de Lenguaje
- Separar el corpus en entrenamiento y test (90% y 10% resp.).
- Usar el script
train.py
para entrenar el modelo “add one” y guardar las instancias resultantes para varios valores de n (1, 2, 3 y 4). - Usar el script
eval.py
para calcular la perplejidad de los modelos entrenados en el ejercicio anterior. Reportar los resultados en el README.
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.
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 claseInterpolatedNGram
. - 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:
-
- Especialmente esta parte (última parte de la sección 1.4.1).
- Mails:
Ejercicio 7 (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.