====== Trabajo Práctico 2 - Análisis de Sentimiento ====== [[materias:pln:2019|(volver a la página principal)]] En este trabajo práctico implementaremos modelos de análisis de sentimiento y haremos algunos experimentos con ellos. * Repositorio: https://github.com/PLN-FaMAF/PLN-2019. * Fecha de entrega: 25/04 2/5 a las 23:59. ===== 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 de Tweets: Estadísticas Básicas ===== Los corpus InterTASS 2018 se componen de conjuntos de tweets en español, cada uno anotado con su polaridad general. Los valores posibles para la polaridad son los siguientes: * ''P'': Polaridad positiva. * ''N'': Polaridad negativa. * ''NEU'': Polaridad neutra. * ''NONE'': Sin polaridad. Puede encontrar una descripción más detallada del significado de cada etiqueta en [[https://cs.famaf.unc.edu.ar/~francolq/criterios_polaridad.pdf|este documento]]. En InterTASS 2018 se proveen corpus de entrenamiento, desarrollo y evaluación para tweets de tres países: España, Costa Rica y Perú. Programar un script ''stats.py'' que muestre las siguientes estadísticas básicas de la sección de entrenamiento del corpus InterTASS: * Cantidad total de tweets. * Cantidad de tweets por cada valor de polaridad (''P'', ''N'', ''NEG'' y ''NONE''). Imprimir estas estadísticas para los tres corpus de InterTASS 2018. Documentación: * TASS: * [[http://www.sepln.org/workshops/tass/2018/task-1|TASS 2018 Task 1]] * [[http://www.sepln.org/workshops/tass/2018/task-1/private/evaluation/evaluate.php|Resultados]] * [[http://ceur-ws.org/Vol-2172/|Proceedings]] * [[http://ceur-ws.org/Vol-2172/p0_overview_tass2018.pdf|Overview]] * [[http://ceur-ws.org/Vol-2172/p2_elirf_tass2018.pdf|ELiRF-UPV (1st place)]] * [[http://ceur-ws.org/Vol-2172/p5_retuyt_tass2018.pdf|RETUYT (2nd place)]] * [[http://ceur-ws.org/Vol-2172/p1_atalaya_tass2018.pdf|Atalaya (3rd place)]] * [[https://competitions.codalab.org/competitions/21957|TASS 2019]] * [[https://cs.famaf.unc.edu.ar/~francolq/criterios_polaridad.pdf|Etiquetado de polaridad]] * [[https://github.com/PLN-FaMAF/PLN-2019/blob/master/notebooks/04%20An%C3%A1lisis%20de%20Sentimiento.ipynb|Jupyter notebook: Análisis de Sentimiento (ejemplo visto en clase)]] * [[https://github.com/DiploDatos/AprendizajeSupervisado/tree/master/sentiment|Caso de Estudio: Sentiment Analysis (Diplomatura Ciencias de Datos)]] ===== Ejercicio 2: Mejoras al Clasificador Básico de Polaridad ===== Implementar, en el clasificador de sentimientos, **cuatro** de las seis posibles mejoras descriptas en las siguientes subsecciones. Para cada mejora, reportar: * Resultado de la evaluación sobre el corpus de development de InterTASS. Usar el script ''eval.py''. ==== Mejor Tokenizer ==== El tokenizer por defecto del ''CountVectorizer'' filtra toda la puntuación y los emojis. Sin embargo los emojis y algunas puntuaciones son indicadoras de sentimiento (e.g. "!" y "?"). Cambiar el tokenizer por uno que no elimine emojis y puntuación. Una opción posible es el tokenizador de NLTK. ==== Binarización de Conteos ==== Modificar la configuración del ''CountVectorizer'' para que ignore las repeticiones de palabras. ==== Normalización Básica de Tweets ==== Preprocesar los textos de los tweets de la siguiente manera: * Eliminar menciones de usuarios. * Eliminar URLs. * Contraer repeticiones de 3 o más vocales. ==== Filtrado de stopwords ==== Modificar el ''CountVectorizer'' para que ignore stopwords del castellano (palabras sin carga semántica como artículos, preposiciones, etc.). Una posible fuente de stopwords es NLTK. ==== Lematización o Stemming ==== Modificar el tokenizador del ''CountVectorizer'' para que además haga stemming o lematización de las palabras. Recursos: * http://scikit-learn.org/stable/modules/feature_extraction.html#customizing-the-vectorizer-classes * Stemmers: * [[http://www.nltk.org/api/nltk.stem.html#module-nltk.stem.snowball|Snowball (NLTK)]] * Lematizadores: * [[https://spacy.io/|Spacy]] * [[http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/|Treetagger]] (con [[https://treetaggerwrapper.readthedocs.io/en/latest/|treetaggerwrapper]]) ==== Manejo de Negaciones ==== Modificar el tokenizador del ''CountVectorizer'' para que además maneje negaciones. Al encontrar una negación ('no', 'tampoco', etc.), deben modificarse todas las palabras hasta el siguiente signo de puntuación, agregándoles el prefijo ''NOT_''. Ejemplo: este verano tampoco ha llegado a hacer calor, sobre todo si lo comparamos con el pasado debe ser reemplazado por: este verano tampoco NOT_ha NOT_llegado NOT_hacer NOT_calor , sobre todo si lo comparamos con el pasado ===== Ejercicio 3: Exploración de Parámetros ("Grid Search") ===== Para los tres tipos de clasificadores, pruebe diferentes combinaciones de parámetros y evalúe sobre el corpus de development. Reporte mejor resultado y configuración para cada clasificador. * [[http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html|Regresión Logística]] (maxent): Probar distintos valores para ''penalty'' y ''C''. * [[http://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html|SVM]]: Probar distintos valores para ''penalty'' y ''C''. Documentación: * **[[https://github.com/PLN-FaMAF/PLN-2019/blob/master/notebooks/sentiment/05%20Grid%20Search.ipynb|Caso de estudio: 05 Grid Search]]** * [[http://scikit-learn.org/stable/modules/grid_search.html|Tuning the hyper-parameters of an estimator (scikit-learn)]] ===== Ejercicio 4: Inspección de Modelos ===== Para la regresión logística, haga una inspección de los parámetros internos: - Imprima para cada clase los 10 features con más peso positivo y los 10 con más peso negativo. - Haga un breve análisis sobre los features impresos: - ¿Tienen sentido en general? - ¿Hay features incorrectos, confusos o engañosos? - ¿De qué manera se podrían corregir? (no hace falta implementar) Documentación: * **[[https://github.com/PLN-FaMAF/PLN-2019/blob/master/notebooks/sentiment/06%20Inspeccion%20de%20Modelos.ipynb|Caso de estudio: 06 Inspeccion de Modelos]]** ===== Ejercicio 5: Análisis de Error ===== Para la regresión logística, haga un análisis de errores sobre el conjunto de development: * Arme una tabla con todas las instancias mal clasificadas. * Ordénelas utilizando algún criterio de relevancia. Ejemplos: * Largo del tweet. * Probabilidad asignada a la clase errónea. * Diferencia entre la probabilidad de la clase errónea y la correcta. Seleccione una instancia mal clasificada: * Imprima los features que intervienen en su clasificación, con su respectivos pesos. * Pruebe variaciones del texto del tweet, viendo de qué manera afecta las probabilidades. * Proponga alguna modificación en el preprocesamiento que pueda mejorar la clasificación de la instancia. Documentación: * **[[https://github.com/PLN-FaMAF/PLN-2019/blob/master/notebooks/sentiment/07%20Analisis%20de%20Error.ipynb|Caso de estudio: 07 Analisis de Error]]** ===== Ejercicio 6: Evaluación Final ===== * Seleccionar, del ejercicio anterior, el clasificador que haya dado mejores resultados. * Calcular y reportar los resultados de la evaluación con el corpus de test final de InterTASS. Usar el script ''eval.py'' con la opción ''-f''. ===== Ejercicio 7 (punto bonus): Word Embeddings ===== * Obtener word embeddings pre-entrenados para el idioma castellano. * Programar un transformador de scikit-learn que, dado un tokenizador, calcule embeddings de tweets como el promedio de los embeddings de las palabras que lo componen. * Incorporar estos features al pipeline de clasificación de polaridad. * Entrenar, evaluar y analizar los resultados. Recursos: * [[https://github.com/scikit-learn/scikit-learn/issues/8978|sklearn issue #8978: Vectorize text based on word embeddings]] * Embeddings: * [[https://fasttext.cc/|fastText]] * [[https://nlp.stanford.edu/projects/glove/|GloVe]] /* ===== Ejercicio 8 (punto bonus): Bolsa de Caracteres ===== */ ===== Ejercicio 8 (punto bonus): Lexicón de Sentimientos (y Emojis) ===== * Obtener o elaborar un lexicón de palabras con polaridad positiva y negativa del castellano. * Programar features que incorporen el uso de estas palabras en los tweets. Algunas opciones: * Dos features, con conteos de cantidad de palabras positivas y negativas utilizadas. * Escalar los valores (usar StandardScaler). * Si el lexicón tiene valores de intensidad, usarlos de alguna manera. * Agregar estos nuevos features al pipeline (se puede usar FeatureUnion). * Entrenar, evaluar y analizar los resultados. Documentación: * **[[https://github.com/PLN-FaMAF/PLN-2019/blob/master/notebooks/sentiment/08%20Lexicon%20de%20Sentimiento.ipynb|Caso de estudio: 08 Lexicon de Sentimiento]]** * Posibles fuentes de lexicones: * [[http://habla.dc.uba.ar/gravano/sdal.php?lang=esp|Spanish DAL: Diccionario de Afectos en Español (Agustín Gravano et al.)]] * [[http://web.eecs.umich.edu/~mihalcea/downloads.html#SPANISH_SENT_LEXICONS|Sentiment Lexicons in Spanish (Veronica Perez Rosas et al.)]] * [[https://github.com/JoseCardonaFigueroa/sentiment-analysis-spanish/blob/master/data/subjectivity.csv]] * [[http://www.lsi.us.es/~fermin/ML-SentiCon.zip|ML-SentiCon: A Layered, Multilingual Sentiment Lexicon (English, Spanish, Catalan, Galician, Basque)]] * **[[http://kt.ijs.si/data/Emoji_sentiment_ranking/index.html|Emoji Sentiment Ranking v1.0]]** * Scikit-learn: * [[http://scikit-learn.org/stable/modules/generated/sklearn.pipeline.FeatureUnion.html|FeatureUnion]] * [[https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html|StandardScaler]] /* ===== Ejercicio 5 (punto bonus): Ensamble de Clasificadores ===== */