{ "cells": [ { "cell_type": "markdown", "id": "7bffde48", "metadata": { "id": "7bffde48" }, "source": [ "# Ciencia de Datos y Lenguaje Natural - **Notebook 2** \n", "## Orientación semántica de opiniones" ] }, { "cell_type": "markdown", "id": "95b60fe0", "metadata": { "id": "95b60fe0" }, "source": [ "En este notebook se trabajará en análisis de sentimientos para el español. El objetivo es predecir si una oración expresa un juicio positivo o negativo. Se trabajará con el corpus CDLN-Senti formado por oraciones simples anotadas según su orientación semántica (positiva, 0; negativa, 1). El corpus se generó a partir de comentarios de usuarios en los sitios de Amazon, IMDB y Yelp. Se encontraba disponible en inglés y fue traducido al español por Google translate. \n", "\n", "Se resolverá el problema propuesto por 2 estrategias distintas. En la primera se aplicará un método simple basado en la cantidad de ocurrencias en los textos de palabras positivas y negativas. La segunda estrategia consiste en aplicar el algoritmo de aprendizaje automático *regresión logística* a un conjunto de *features* diseñadas para este problema. Se debe realizar una evaluación completa y comparación de los resultados.\n", "\n", "#### Indique nombre, número de cédula y que carrera está cursando" ] }, { "cell_type": "code", "execution_count": null, "id": "6b206516", "metadata": { "id": "6b206516" }, "outputs": [], "source": [ "__author__ = \"Nombre Apellido\"\n", "__cedula__ = \"1.234.567-8\"\n", "__origen__ = \"Grado. Ing. Computación\"" ] }, { "cell_type": "markdown", "id": "14d82f69", "metadata": {}, "source": [ "## Lectura de datos (corpus y léxicos)\n", "\n", "Se dispone de dos léxicos para el español, uno de palabras positivas (palabras-pos.txt) y otro de palabras negativas (palabras-neg.txt). Descarguelos del eva del curso. (Los léxicos fueron extraídos de: https://www.kaggle.com/datasets/rtatman/sentiment-lexicons-for-81-languages?resource=download)\n", "\n", "Se dispone además de un corpus con los datos de las opiniones en el formato \"frase|valor\", donde \"frase\" es la frase a analizar (Ej. \"Me encantó. Volveré.\") y \"valor\" es 0 o 1. Este coprpus se encuentra fraccionado en entrenamiento (senti-train.csv), validación (senti-val.csv) y test (senti-test.csv). \n", "\n", "En el siguiente bloque de código se leen y cargan en memoria los léxicos y el corpus de análisis de sentimiento. Estos recursos serán utilizados a lo largo de todo el notebook. " ] }, { "cell_type": "code", "execution_count": null, "id": "ef8bee60", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import os\n", "import csv\n", "import sklearn\n", "\n", "def read_data(path):\n", " import csv\n", " rows=[]\n", " with open(path, encoding='utf-8') as doc:\n", " csvreader = csv.reader(doc, delimiter ='|', quoting=csv.QUOTE_NONE)\n", " for i,row in enumerate(csvreader):\n", " rows.append(row)\n", " if len(rows)>0 and len(rows[0])==1:\n", " rows = [r[0] for r in rows]\n", " return rows\n", "\n", "\n", "dtrain = read_data('./senti-train.csv')\n", "dval = read_data('./senti-val.csv')\n", "dtest = read_data('./senti-test.csv')\n", "lexpos = read_data('./palabras-pos.txt')\n", "lexneg = read_data('./palabras-neg.txt')" ] }, { "cell_type": "markdown", "id": "caf64dbc", "metadata": {}, "source": [ "**Cantidad de elementos de corpus y léxicos**\n", "\n", "Despliegue para el corpus cantidad de entradas positivas y negativas en cada partición (train, val, test).\n", "Además, despliegue cantidad de elementos de cada léxico, positivo y negativo." ] }, { "cell_type": "code", "execution_count": null, "id": "2df24ee0", "metadata": {}, "outputs": [], "source": [ "# Código para desplegar valores" ] }, { "cell_type": "markdown", "id": "ccb6f0fc", "metadata": { "id": "ccb6f0fc" }, "source": [ "## I. Algoritmo simple para determinar la orientación semántica de una oración\n", "\n", "En esta primera parte se utilizarán estos léxicos para determinar si una oración del corpus CDLN-senti representa un juicio positivo o negativo. El método consiste simplemente en contar cuantas palabras positivas y cuantas negativas tiene la oración. Si la cantidad de negativas supera a la de positivas, la opinión se clasifica como negativa. En caso contrario será positiva. Interesa distinguir casos en que no hay palabras positivas ni negativas en la opinión (de acuerdo a las listas) o en que tienen la misma cantidad de palabras positivas y negativas. " ] }, { "cell_type": "markdown", "id": "u9PeSkOWdmUZ", "metadata": { "id": "u9PeSkOWdmUZ" }, "source": [ "### 1. Implementación del algoritmo\n", "#### Implemente el algoritmo considerando la siguiente especificación:\n", "\n", "1. Recibe como entrada un dataset (train, val o test) y dos listas de palabras (positivas y negativas). \n", "1. Para cada opinión del dataset analiza cada palabra si la palabra, o su lema, se encuentra en alguna de las listas. Al procesar una opinión se puede producir una de 4 situaciones: \n", " - La cantidad de palabras negativas supera a la de positivas, la opinión se clasifica como **negativa** (0)\n", " - La cantidad de palabras positivas supera a la de negativas, la opinión se clasifica como **positiva**. (1) \n", " - Las cantidades coinciden, siendo distintas de cero, se marca como **indefinida**. (2) \n", " - No tiene palabras en las listas, se marca como **sin información** (3)\n", "1. Retorna una lista de valores (0,1,2 y 3) con la clasificación de cada opinión.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "5137b6cb", "metadata": { "id": "5137b6cb" }, "outputs": [], "source": [ "# Código del programa" ] }, { "cell_type": "markdown", "id": "75298f0f", "metadata": {}, "source": [ "##### Al procesar una opinión se puede producir una de 4 situaciones: \n", "- La opinión se marca con un juicio inverso al de los datos, este caso es un caso de **error**. \n", "- La opinión se marca con el mismo juicio que aparece en los datos, este es el caso de **éxito**. \n", "- La opinión tiene palabras positivas y negativas y las cantidades coinciden, se marca como **indefinido**. \n", "- La opinión no tiene palabras en las listas, se marca como **sin información** \n", "\n", "**Despliegue las cantidades de opiniones para cada caso usando el conjunto de *train* y 10 ejemplos de cada uno de los casos.**" ] }, { "cell_type": "code", "execution_count": null, "id": "59988f5b", "metadata": {}, "outputs": [], "source": [ "# Código del programa" ] }, { "cell_type": "markdown", "id": "6d39a2fe", "metadata": { "id": "6d39a2fe" }, "source": [ "### 2. Análisis de errores del método\n", "Analice 3 casos de **error**, 3 casos de tipo **indefinido** y 3 **sin información** en el conjunto de *train*. Tenga en cuenta temas como la ironía, o la negación, así como que es posible que haya términos negativos y positivos que dependan del dominio del cual trata el texto.\n", "\n", "**Respuesta:**" ] }, { "cell_type": "markdown", "id": "67bfc3ee", "metadata": { "id": "67bfc3ee" }, "source": [ "*Escriba aquí su respuesta*" ] }, { "cell_type": "markdown", "id": "2eb85274", "metadata": { "id": "2eb85274" }, "source": [ "### 3. Análisis de métodos para la construcción de léxicos de sentimiento\n", "\n", "Parte de los problemas reportados en el punto anterior puede deberse a problemas de calidad en los léxicos de sentimiento. Estos suelen compilarse de modo semiautomático. Por ejemplo, algunos de los métodos utilizados parten de un conjunto inicial pequeño y lo expanden según medidas de similitud.\n", "\n", "Se pide que lean el siguiente artículo sobre léxico análisis de sentimientos y realicen un resumen del método utilizado y los eventuales problemas (no más de 800 palabras).\n", "\n", "https://aclanthology.org/P02-1053.pdf\n", "\n", "**Respuesta:**" ] }, { "cell_type": "markdown", "id": "99978625", "metadata": { "id": "99978625" }, "source": [ "*Escriba aquí su respuesta*" ] }, { "cell_type": "markdown", "id": "00bcaa7e", "metadata": {}, "source": [ "### 4. Resultados\n", "Reporte los resultados obtenidos (precision, recall y F) en el conjunto de *test*. Tenga en cuenta que para este punto las opiniones clasificadas con 1, 2 o 3 son consideradas positivas.\n", "\n", "Fuente sugerida: https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_recall_fscore_support.html" ] }, { "cell_type": "code", "execution_count": null, "id": "bdf3a925", "metadata": {}, "outputs": [], "source": [ "# Código de su respuesta" ] }, { "cell_type": "markdown", "id": "e56c8868", "metadata": { "id": "e56c8868" }, "source": [ "## II. Orientación semántica de opiniones por regresión logística\n", "\n", "Genere un modelo de regresión logística para la detección de la orientación semántica utilizando como entrada un conjunto de atributos que considere adecuados. Reporte valores de evaluación de su modelo. Compare con el método anterior.\n", "\n", "### 1. Atributos del modelo \n", "\n", "Indique que atributos considera en su modelo:" ] }, { "cell_type": "markdown", "id": "08ea6bc6", "metadata": {}, "source": [ "*Escriba aquí su respuesta*\n", "\n", "- atributo 1\n", "- atributo 2\n", "- ..." ] }, { "cell_type": "markdown", "id": "b7e5d90f", "metadata": {}, "source": [ "### 2. Definición y entrenamiento\n", "\n", "Escriba el código para definir y entrenar su modelo.\n", "\n", "Fuentes sugeridas: \n", "- https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html\n", "- https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html" ] }, { "cell_type": "code", "execution_count": null, "id": "833778ae", "metadata": {}, "outputs": [], "source": [ "# Código de su respuesta" ] }, { "cell_type": "markdown", "id": "eafb6e95", "metadata": {}, "source": [ "**Despligue medidas de evaluación (accuracy, precision, recall y f) para los conjuntos de *train* y *val*.**" ] }, { "cell_type": "code", "execution_count": null, "id": "aabd4c1f", "metadata": {}, "outputs": [], "source": [ "# Código de su respuesta" ] }, { "cell_type": "markdown", "id": "9098835d", "metadata": {}, "source": [ "### 3. Búsqueda de hiperparámetros\n", "\n", "Realice una búsqueda manual para los hiperparámetros de su modelo. Pruebe distintas configuraciones y reporte los resultados. Elija una configuración como modelo final. \n", "\n", "Recuerde que la elección de hiperparámetros debe realizarse usando los conjuntos *train* y *val*. " ] }, { "cell_type": "markdown", "id": "3ac51f08", "metadata": {}, "source": [ "*Escriba aquí su respuesta*" ] }, { "cell_type": "code", "execution_count": null, "id": "baf02430", "metadata": {}, "outputs": [], "source": [ "# Código de su respuesta" ] }, { "cell_type": "markdown", "id": "78adbe82", "metadata": {}, "source": [ "### 4. Resultados\n", "**Reporte los resultados obtenidos (accuracy, precision, recall y F) en el conjunto de *test*.**" ] }, { "cell_type": "code", "execution_count": null, "id": "b080af74", "metadata": {}, "outputs": [], "source": [ "# Código de su respuesta" ] }, { "cell_type": "markdown", "id": "b3daa19d", "metadata": {}, "source": [ "# Referencias\n", "\n", "- Speech and Language Processing (3rd ed. draft). Dan Jurafsky and James H. Martin. Cap 5. https://web.stanford.edu/~jurafsky/slp3/5.pdf \n", "- Opinion mining and sentiment analysis. Pang, Bo, and Lillian Lee. Foundations and Trends® in information retrieval 2.1–2 (2008): 1-135. https://www.cs.cornell.edu/home/llee/omsa/omsa.pdf\n", "- https://docs.python.org/3/\n", "- https://scikit-learn.org/stable/\n", "- https://spacy.io/\n" ] } ], "metadata": { "colab": { "collapsed_sections": [], "provenance": [] }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 5 }