====== Trabajo Práctico 3 - Etiquetado de Secuencias ======
[[materias:pln:2019|(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 [[https://github.com/PLN-FaMAF/PLN-2019|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:
* [[http://clic.ub.edu/corpus/|Corpus AnCora]]
* [[https://web.archive.org/web/20160325024315/http://nlp.lsi.upc.edu/freeling/doc/tagsets/tagset-es.html|Etiquetas EAGLES]]
* [[https://nlp.stanford.edu/software/spanish-faq.shtml#tagset|Stanford CoreNLP simplified tagset]]
* [[https://github.com/PLN-FaMAF/PLN-2019/blob/master/notebooks/tagging/01%20Etiquetado%20de%20Secuencias.ipynb|Jupyter notebook: Etiquetado de Secuencias]]
===== 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:
* http://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html
===== 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:
* http://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html
===== 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:
* [[http://www.cs.columbia.edu/~mcollins/hmms-spring2013.pdf]]
===== 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:
* [[http://www.cs.columbia.edu/~mcollins/hmms-spring2013.pdf]]
===== 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**
/*
===== Ejercicio 9: Red Neuronal =====
===== Ejercicio 10: Red Neuronal Recurrente =====
* https://allennlp.org/tutorials
* https://pytorch.org/tutorials/beginner/nlp/sequence_models_tutorial.html#example-an-lstm-for-part-of-speech-tagging
*/