Tabla de Contenidos
Trabajo Práctico 3 - Etiquetado de Secuencias
(volver a la página principal)
En este trabajo práctico implementaremos varios modelos de etiquetado de secuencias y realizaremos algunos experimentos con ellos.
- Repositorio: https://github.com/PLN-FaMAF/PLN-2019.
- Fecha de entrega: TBA.
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 tagging
.
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 AnCora: Estadísticas de etiquetas POS
Programar un script stats.py
que muestre la siguiente información del corpus:
- Estadísticas básicas:
- Cantidad de oraciones.
- Cantidad de ocurrencias de palabras.
- Cantidad de palabras (vocabulario).
- Cantidad de etiquetas (vocabulario de tags).
- Etiquetas más frecuentes: Una tabla con las 10 etiquetas más frecuentes y la siguiente información para cada una:
- Cantidad de veces que aparece (frecuencia), y porcentaje del total.
- Cinco palabras más frecuentes con esa etiqueta.
- En el README, agregar a mano una breve descripción del significado de la etiqueta.
- Niveles de ambigüedad de las palabras: Una figura similar a la Figura 5.10 de Jurafsky & Martin (2008). Para cada nivel de ambigüedad (de 1 a 9) mostrar:
- Cantidad de palabras y porcentaje del total.
- Cinco palabras más frecuentes.
- Incluir todas las estadísticas en el README.
Uso del script:
$ python tagging/scripts/stats.py
Documentación:
Ejercicio 2: Baseline Tagger
- Programar un etiquetador baseline, que elija para cada palabra su etiqueta más frecuente observada en entrenamiento.
- Para las palabras desconocidas, devolver la etiqueta 'nc0s000' (nombre común singular).
- Entrenar y evaluar el modelo baseline del ejercicio anterior. Reportar los resultados en el README.
- Bonus: Graficar la matriz de confusión como un mapa de calor (ver documentación abajo).
Interfaz de BaselineTagger
en baseline.py
:
class BaselineTagger: def __init__(self, tagged_sents, default_tag='nc0s000'): """ tagged_sents -- training sentences, each one being a list of pairs. default_tag -- tag for unknown words. """ def tag(self, sent): """Tag a sentence. sent -- the sentence. """ def tag_word(self, w): """Tag a word. w -- the word. """ def unknown(self, w): """Check if a word is unknown for the model. w -- the word. """
Tests:
$ nosetests tagging/tests/test_baseline.py
Ejemplo de uso de los scripts:
$ python tagging/scripts/train.py -o baseline $ python tagging/scripts/eval.py -i baseline
Documentación:
Ejercicio 3: Entrenamiento y Evaluación de Taggers
- Programar un script
train.py
que permita entrenar un etiquetador baseline. - Programar un script
eval.py
que permita evaluar un modelo de tagging. Calcular:- Accuracy, esto es, el porcentaje de etiquetas correctas.
- Accuracy sobre las palabras conocidas y sobre las palabras desconocidas.
- Matriz de confusión, como se explica en la sección 5.7.1 (Error Analysis) de Jurafsky & Martin.
- Entrenar y evaluar el modelo baseline del ejercicio anterior. Reportar los resultados en el README.
- Bonus: Graficar la matriz de confusión como un mapa de calor (ver documentación abajo).
Ejemplo de uso de los scripts:
$ python tagging/scripts/train.py -o baseline $ python tagging/scripts/eval.py -i baseline
Documentación:
Ejercicio 4: Hidden Markov Models y Algoritmo de Viterbi
- Implementar un Hidden Markov Model cuyos parámetros son las probabilidades de transición entre estados (las etiquetas) y de emisión de símbolos (las palabras).
- Implementar el algoritmo de Viterbi que calcula el etiquetado más probable de una oración.
Interfaz de HMM
y ViterbiTagger
en hmm.py
:
class HMM: def __init__(self, n, tagset, trans, out): """ n -- n-gram size. tagset -- set of tags. trans -- transition probabilities dictionary. out -- output probabilities dictionary. """ def tagset(self): """Returns the set of tags. """ def trans_prob(self, tag, prev_tags): """Probability of a tag. tag -- the tag. prev_tags -- tuple with the previous n-1 tags (optional only if n = 1). """ def out_prob(self, word, tag): """Probability of a word given a tag. word -- the word. tag -- the tag. """ def tag_prob(self, y): """ Probability of a tagging. Warning: subject to underflow problems. y -- tagging. """ def prob(self, x, y): """ Joint probability of a sentence and its tagging. Warning: subject to underflow problems. x -- sentence. y -- tagging. """ def tag_log_prob(self, y): """ Log-probability of a tagging. y -- tagging. """ def log_prob(self, x, y): """ Joint log-probability of a sentence and its tagging. x -- sentence. y -- tagging. """ def tag(self, sent): """Returns the most probable tagging for a sentence. sent -- the sentence. """ class ViterbiTagger: def __init__(self, hmm): """ hmm -- the HMM. """ def tag(self, sent): """Returns the most probable tagging for a sentence. sent -- the sentence. """
Tests:
$ nosetests tagging/tests/test_hmm.py $ nosetests tagging/tests/test_viterbi_tagger.py
Documentación:
Ejercicio 5: HMM POS Tagger
- Implementar en una clase
MLHMM
un Hidden Markov Model cuyos parámetros se estiman usando Maximum Likelihood sobre un corpus de oraciones etiquetado. - La clase debe tener la misma interfaz que
HMM
con las modificaciones y agregados especificadas abajo. - Agregar al script de entrenamiento (train.py) una opción de línea de comandos que permita utilizar la MLHMM con distintos valores de
n
. - Entrenar y evaluar para varios valores de
n
(1, 2, 3 y 4). Reportar los resultados en el README. Reportar también tiempo de evaluación.
Interfaz de MLHMM
en hmm.py
:
class MLHMM: def __init__(self, n, tagged_sents, addone=True): """ n -- order of the model. tagged_sents -- training sentences, each one being a list of pairs. addone -- whether to use addone smoothing (default: True). """ def tcount(self, tokens): """Count for an n-gram or (n-1)-gram of tags. tokens -- the n-gram or (n-1)-gram tuple of tags. """ def unknown(self, w): """Check if a word is unknown for the model. w -- the word. """ """ Todos los métodos de HMM. """
Tests:
$ nosetests tagging/tests/test_ml_hmm.py
Documentación:
Ejercicio 6: Clasificador "three words"
TBA
Ejercicio 7: Clasificador con Embeddings
TBA
Ejercicio 8: Análisis de Error y Nuevos Features
TBA
Ejercicio 9: Red Neuronal Recurrente
TBA