Skip to content
Snippets Groups Projects
Commit 5c9f714f authored by Braulio Ríos's avatar Braulio Ríos
Browse files

Actualizado notebook Tarea 2

parent 1298b269
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# Introducción a la Ciencia de Datos: Tarea 2 # Introducción a la Ciencia de Datos: Tarea 2
Este notebook contiene el código de base para realizar la Tarea 2 del curso. Puede copiarlo en su propio repositorio y trabajar sobre el mismo. Este notebook contiene el código de base para realizar la Tarea 2 del curso. Puede copiarlo en su propio repositorio y trabajar sobre el mismo.
Las **instrucciones para ejecutar el notebook** están en la [página inicial del repositorio](https://gitlab.fing.edu.uy/maestria-cdaa/intro-cd/). Las **instrucciones para ejecutar el notebook** están en la [página inicial del repositorio](https://gitlab.fing.edu.uy/maestria-cdaa/intro-cd/).
**Se espera que no sea necesario revisar el código para corregir la tarea**, ya que todos los resultados y análisis relevantes deberían estar en el **informe en formato PDF**. **Se espera que no sea necesario revisar el código para corregir la tarea**, ya que todos los resultados y análisis relevantes deberían estar en el **informe en formato PDF**.
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Cargar dependencias ## Cargar dependencias
Para esta tarea, se han agregado algunos requerimientos, asegúrese de instalarlos (puede usar el mismo entorno virtual de la Tarea 1): Para esta tarea, se han agregado algunos requerimientos, asegúrese de instalarlos (puede usar el mismo entorno virtual de la Tarea 1):
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
!pip install jupyter pandas "sqlalchemy<2.0" pymysql seaborn pillow scikit-learn !pip install jupyter pandas "sqlalchemy<2.0" pymysql seaborn pillow scikit-learn
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
from time import time from time import time
from pathlib import Path from pathlib import Path
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from sqlalchemy import create_engine from sqlalchemy import create_engine
# Agregamos scikit-learn como dependencia en requirements.txt
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.naive_bayes import MultinomialNB from sklearn.naive_bayes import MultinomialNB
from sklearn.neighbors import KNeighborsClassifier from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split from sklearn.model_selection import train_test_split
from sklearn.metrics import ConfusionMatrixDisplay from sklearn.metrics import ConfusionMatrixDisplay
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Conexión a la Base y Lectura de Datos ## Conexión a la Base y Lectura de Datos
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# Creamos el directorio Tarea_1/data/shakespeare
data_dir = Path("data") / "shakespeare" data_dir = Path("data") / "shakespeare"
data_dir.mkdir(parents=True, exist_ok=True) data_dir.mkdir(parents=True, exist_ok=True)
def load_table(table_name, engine): def load_table(table_name, engine):
""" """
Leer la tabla con SQL y guardarla como CSV, Leer la tabla con SQL y guardarla como CSV,
o cargarla desde el CSV si ya existe o cargarla desde el CSV si ya existe
""" """
path_table = data_dir / f"{table_name}.csv" path_table = data_dir / f"{table_name}.csv"
if not path_table.exists(): if not path_table.exists():
print(f"Consultando tabla con SQL: {table_name}") print(f"Consultando tabla con SQL: {table_name}")
t0 = time() t0 = time()
df_table = pd.read_sql(f"SELECT * FROM {table_name}", engine) df_table = pd.read_sql(f"SELECT * FROM {table_name}", engine)
t1 = time() t1 = time()
print(f"Tiempo: {t1 - t0:.1f} segundos") print(f"Tiempo: {t1 - t0:.1f} segundos")
print(f"Guardando: {path_table}\n") print(f"Guardando: {path_table}\n")
df_table.to_csv(path_table) df_table.to_csv(path_table)
else: else:
print(f"Cargando tabla desde CSV: {path_table}") print(f"Cargando tabla desde CSV: {path_table}")
df_table = pd.read_csv(path_table, index_col=[0]) df_table = pd.read_csv(path_table, index_col=[0])
return df_table return df_table
print("Conectando a la base...") print("Conectando a la base...")
conn_str = "mysql+pymysql://guest:relational@relational.fit.cvut.cz:3306/Shakespeare" conn_str = "mysql+pymysql://guest:relational@relational.fit.cvut.cz:3306/Shakespeare"
engine = create_engine(conn_str) engine = create_engine(conn_str)
# Todos los párrafos de todas las obras # Todos los párrafos de todas las obras
df_paragraphs = load_table("paragraphs", engine) df_paragraphs = load_table("paragraphs", engine)
df_characters = load_table("characters", engine) df_characters = load_table("characters", engine)
df_works = load_table("works", engine) df_works = load_table("works", engine)
df_chapters = load_table("chapters", engine) df_chapters = load_table("chapters", engine)
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
df_paragraphs df_paragraphs
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Limpieza de Texto ## Limpieza de Texto
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# TODO: Actualizar con su versión de clean_text() en la Tarea_1 # TODO: Actualizar con su versión de clean_text() de la Tarea_1
def clean_text(df, column_name): def clean_text(df, column_name):
# Convertir todo a minúsculas # Convertir todo a minúsculas
result = df[column_name].str.lower() result = df[column_name].str.lower()
# FIXME: # FIXME: completar
for punc in ["[", "\n", ","]: for punc in ["[", "\n", ","]:
result = result.str.replace(punc, " ") result = result.str.replace(punc, " ")
return result return result
# Creamos una nueva columna CleanText a partir de PlainText # Creamos una nueva columna CleanText a partir de PlainText
df_paragraphs["CleanText"] = clean_text(df_paragraphs, "PlainText") df_paragraphs["CleanText"] = clean_text(df_paragraphs, "PlainText")
# Veamos la diferencia # Veamos la diferencia
df_paragraphs[["PlainText", "CleanText"]] df_paragraphs[["PlainText", "CleanText"]]
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# Agregamos personajes, obras y géneros en el mismo dataset # Agregamos personajes, obras y géneros en el mismo dataset
df_dataset = df_paragraphs.merge(df_chapters.set_index("id")["work_id"], left_on="chapter_id", right_index=True) df_dataset = df_paragraphs.merge(df_chapters.set_index("id")["work_id"], left_on="chapter_id", right_index=True)
df_dataset = df_dataset.merge(df_works.set_index("id")[["Title", "GenreType"]], left_on="work_id", right_index=True) df_dataset = df_dataset.merge(df_works.set_index("id")[["Title", "GenreType"]], left_on="work_id", right_index=True)
df_dataset = df_dataset.merge(df_characters.set_index('id')["CharName"], left_on="character_id", right_index=True).sort_index() df_dataset = df_dataset.merge(df_characters.set_index('id')["CharName"], left_on="character_id", right_index=True).sort_index()
df_dataset = df_dataset[["CleanText", "CharName", "Title", "GenreType"]] df_dataset = df_dataset[["CleanText", "CharName", "Title", "GenreType"]]
# Usaremos sólo estos personajes # Usaremos sólo estos personajes
characters = ["Antony", "Cleopatra", "Queen Margaret"] characters = ["Antony", "Cleopatra", "Queen Margaret"]
df_dataset = df_dataset[df_dataset["CharName"].isin(characters)] df_dataset = df_dataset[df_dataset["CharName"].isin(characters)]
df_dataset df_dataset
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# Párrafos por cada personaje seleccionado # Párrafos por cada personaje seleccionado
df_dataset["CharName"].value_counts() df_dataset["CharName"].value_counts()
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Dataset y Features de texto ## Dataset y Features de texto
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
X = df_dataset["CleanText"].to_numpy() X = df_dataset["CleanText"].to_numpy()
y = df_dataset["CharName"].to_numpy() y = df_dataset["CharName"].to_numpy()
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# TODO: Partir train/test 30% estratificados # TODO: Partir train/test 30% estratificados
# -> Definir X_train, X_test, y_train, y_test # -> Definir X_train, X_test, y_train, y_test
# X_train, X_test, y_train, y_test = ... # X_train, X_test, y_train, y_test = ...
print(f"Tamaños de Train/Test: {len(X_train)}/{len(X_test)}") print(f"Tamaños de Train/Test: {len(X_train)}/{len(X_test)}")
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Conteo de palabras y TF-IDF ### Conteo de palabras y TF-IDF
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
count_vect = CountVectorizer(stop_words=None, ngram_range=(1,1)) count_vect = CountVectorizer(stop_words=None, ngram_range=(1,1))
X_train_counts = count_vect.fit_transform(X_train) X_train_counts = count_vect.fit_transform(X_train)
X_train_counts X_train_counts
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
tf_idf = TfidfTransformer(use_idf=False) tf_idf = TfidfTransformer(use_idf=False)
X_train_tf = tf_idf.fit_transform(X_train_counts) X_train_tf = tf_idf.fit_transform(X_train_counts)
X_train_tf X_train_tf
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Reducción de dimensionalidad ### Reducción de dimensionalidad
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# TODO: Realizar PCA sobre los datos de entrenamiento # TODO: Realizar PCA sobre los datos de entrenamiento
# reductor = ... # reductor = ...
# Transformar train # Transformar train
X_train_red = reductor.fit_transform(X_train_tf.toarray()) X_train_red = reductor.fit_transform(X_train_tf.toarray())
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# Visualización de las dos primeras componentes de PCA # Visualización de las dos primeras componentes de PCA
fig, ax = plt.subplots(figsize=(6, 6)) fig, ax = plt.subplots(figsize=(6, 6))
for character in np.unique(y_train): for character in np.unique(y_train):
mask_train = y_train == character mask_train = y_train == character
ax.scatter(X_train_red[mask_train, 0], X_train_red[mask_train, 1], label=character) ax.scatter(X_train_red[mask_train, 0], X_train_red[mask_train, 1], label=character)
ax.set_title("PCA por personaje") ax.set_title("PCA por personaje")
ax.legend() ax.legend()
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Modelos de Clasificación ## Modelos de Clasificación
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
bayes_clf = MultinomialNB().fit(X_train_tf, y_train) bayes_clf = MultinomialNB().fit(X_train_tf, y_train)
# Ver las primeras 10 predicciones de train # Ver las primeras 10 predicciones de train
y_pred_train = bayes_clf.predict(X_train_tf) y_pred_train = bayes_clf.predict(X_train_tf)
y_pred_train[:10] y_pred_train[:10]
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
def get_accuracy(y_true, y_pred): def get_accuracy(y_true, y_pred):
return (y_true == y_pred).sum() / len(y_true) return (y_true == y_pred).sum() / len(y_true)
get_accuracy(y_train, y_pred_train) get_accuracy(y_train, y_pred_train)
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# TODO: Predecir para test y ver la matriz de confusión, y reportar accuracy # TODO: Predecir para test y ver la matriz de confusión, y reportar accuracy
# X_test_counts = ... # X_test_counts = ...
# X_test_tfidf = ... # X_test_tfidf = ...
# y_test_pred = ... # y_test_pred = ...
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### Búsqueda de hiper-parámetros con Cross-Validation ### Búsqueda de hiper-parámetros con Cross-Validation
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
from sklearn.model_selection import StratifiedKFold from sklearn.model_selection import StratifiedKFold
# TODO: Agregar más variantes de parámetros que les parezcan relevantes # TODO: Agregar más variantes de parámetros que les parezcan relevantes
param_sets = [{"stop_words": None, "ngram": (1,2), "idf": True}, param_sets = [{"stop_words": None, "ngram": (1,2), "idf": True},
{"stop_words": None, "ngram": (1,1), "idf": False}] {"stop_words": None, "ngram": (1,1), "idf": False}]
skf = StratifiedKFold(n_splits=4, shuffle=True, random_state=42) skf = StratifiedKFold(n_splits=4, shuffle=True, random_state=42)
# Ahora usaremos train/validation/test # Ahora usaremos train/validation/test
# Por lo tanto le renombramos train+validation = dev(elopment) dataset # Por lo tanto le renombramos train+validation = dev(elopment) dataset
X_dev = X_train X_dev = X_train
y_dev = y_train y_dev = y_train
# # Para evitar errores # # Para evitar errores
# del X_train # del X_train
# del y_train # del y_train
for params in param_sets: for params in param_sets:
# Transormaciones a aplicar (featurizers) # Transormaciones a aplicar (featurizers)
count_vect = CountVectorizer(stop_words=params["stop_words"], ngram_range=params["ngram"]) count_vect = CountVectorizer(stop_words=params["stop_words"], ngram_range=params["ngram"])
tf_idf = TfidfTransformer(use_idf=params["idf"]) tf_idf = TfidfTransformer(use_idf=params["idf"])
for train_idxs, val_idxs in skf.split(X_dev, y_dev): for train_idxs, val_idxs in skf.split(X_dev, y_dev):
# Train y validation para el split actual # Train y validation para el split actual
X_train_ = X_dev[train_idxs] X_train_ = X_dev[train_idxs]
y_train_ = y_dev[train_idxs] y_train_ = y_dev[train_idxs]
X_val = X_dev[val_idxs] X_val = X_dev[val_idxs]
y_val = y_dev[val_idxs] y_val = y_dev[val_idxs]
# Ajustamos y transformamos Train # Ajustamos y transformamos Train
X_train_counts = count_vect.fit_transform(X_train_) X_train_counts = count_vect.fit_transform(X_train_)
X_train_tf = tf_idf.fit_transform(X_train_counts) X_train_tf = tf_idf.fit_transform(X_train_counts)
# TODO: Completar el código para entrenar y evaluar # TODO: Completar el código para entrenar y evaluar
# Entrenamos con Train # Entrenamos con Train
# bayes_clf = ... # bayes_clf = ...
# Transformamos Validation # Transformamos Validation
# X_val_counts = ... # X_val_counts = ...
# X_val_tfidf = ... # X_val_tfidf = ...
# Predecimos y evaluamos en Validation # Predecimos y evaluamos en Validation
y_pred_val = bayes_clf.predict(X_val_tfidf) y_pred_val = bayes_clf.predict(X_val_tfidf)
acc = get_accuracy(y_val, y_pred_val) acc = get_accuracy(y_val, y_pred_val)
print(f"{acc=:.4f} {params=}") print(f"{acc=:.4f} {params=}")
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
### (Opcional) Comparativa con Fasttext ### (Opcional) Comparativa con Fasttext
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
!pip install fasttext !pip install fasttext
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
import fasttext import fasttext
y_train_s = np.char.replace(y_train.astype(str), " ", "_").astype(object) y_train_s = np.char.replace(y_train.astype(str), " ", "_").astype(object)
y_test_s = np.char.replace(y_test.astype(str), " ", "_").astype(object) y_test_s = np.char.replace(y_test.astype(str), " ", "_").astype(object)
# Convertimos al formato de fasttext: archivo de texto donde cada línea es: # Convertimos al formato de fasttext: archivo de texto donde cada línea es:
# __label__<label> TEXTO # __label__<label> TEXTO
Xytrains = "__label__" + y_train_s.astype(object) + " " + X_train Xytrains = "__label__" + y_train_s.astype(object) + " " + X_train
Xytests = "__label__" + y_test_s.astype(object) + " " + X_test Xytests = "__label__" + y_test_s.astype(object) + " " + X_test
np.savetxt(data_dir / "train.txt", Xytrains, fmt="%s") np.savetxt(data_dir / "train.txt", Xytrains, fmt="%s")
np.savetxt(data_dir / "test.txt", Xytests, fmt="%s") np.savetxt(data_dir / "test.txt", Xytests, fmt="%s")
Xytests[0] Xytests[0]
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
model = fasttext.train_supervised(input=str(data_dir / "train.txt"), epoch=100, wordNgrams=2) model = fasttext.train_supervised(input=str(data_dir / "train.txt"), epoch=100, wordNgrams=2)
model.test(str(data_dir / "test.txt")) model.test(str(data_dir / "test.txt"))
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
y_out = model.predict(list(X_test)) y_out = model.predict(list(X_test))
y_pred_test = [y[0].replace("__label__", "") for y in y_out[0]] y_pred_test = [y[0].replace("__label__", "") for y in y_out[0]]
print(get_accuracy(y_test_s, y_pred_test)) print(get_accuracy(y_test_s, y_pred_test))
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
``` ```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment