<jupyter_start><jupyter_text>Preprocesamiento del corpusEl primer paso para trabajar en este curso es el preprocesamiento del corpus sobre el cuál realizaremos los experimentos de _vector space models_ (o modelos vectoriales). En este notebook se mostrarán los pasos utilizados para obtener, limpiar y preprocesar un corpus para esta tarea.Si bien el curso de CS224u provee dos corpus para ello, se decidió utilizar algo más local, en este caso utilizaremos el corpus del [InfoLEG](http://www.infoleg.gob.ar/), una base de datos legislativos del Ministerio de Justicia y Derechos Humanos de la Nación.Mostraremos como se realiza el preproceso del corpus y las decisiones tomadas a cada paso. Al final del notebook se deja el link para descargar los archivos ya preprocesados (de manera que no tengan que hacerlo localmente). Sin embargo, se recomienda leer el notebook para entender el procedimiento.<jupyter_code>__author__ = "<NAME>"<jupyter_output><empty_output><jupyter_text>Contenidos1. [Descarga del corpus](Descarga-del-corpus)2. [Tokenización y conteo de palabras](Tokenización-y-conteo-de-palabras)3. [Descarga de los modelos](Descarga-de-los-modelos)4. [Carga de los modelos](Carga-de-los-modelos)  Descarga del corpusPara descargar (y descomprimir) el corpus localmente, simplemente basta con activar la siguiente celda. Este es el corpus "crudo", sin ningún tipo de preproceso (más que la eliminación de las etiquetas HTML). Esta es una versión obtenida del corpus por el grupo de PLN en el año 2018.<jupyter_code>%%bash

# Con el comando de arriba indicamos que esta celda se ejecuta sobre BASH en lugar de Python

mkdir -p ./data/
curl -L -o ./data/infoleg.tar.bz2 https://cs.famaf.unc.edu.ar/\~ccardellino/resources/infoleg/infoleg_text.tar.bz2
tar xf ./data/infoleg.tar.bz2 -C data/
rm -f ./data/infoleg.tar.bz2  # Eliminamos el archivo tar.bz2 para ahorrar espacio<jupyter_output><empty_output><jupyter_text>Tokenización y conteo de palabrasEl primer paso para trabajar con modelos vectoriales es crear matrices de co-ocurrencia entre palabras. Siguiendo con los lineamientos del curso CS224u, diseñaremos un par de matrices con las siguientes características:- Las matrices son de co-ocurrencia de palabra $\times$ palabra.- Sólo tienen en cuenta las 5000 palabras más comunes en el corpus (i.e. $M \in \mathbb{R}^{5000\times5000}$).- Crearemos dos matrices:     1. Con ventana 20 y sin escalar.    2. Con ventana 5 y escalando de acuerdo a la distancia sobre la palabra central.- Para aquellas palabras que no estén en nuestro vocabulario, utilizaremos el token _UNK_ y crearemos un vector en base al mismo.Una vez decididos los parámetros de nuestros modelos, se siguen las instrucciones del [notebook del curso CS224u](https://github.com/cgpotts/cs224u/blob/master/vsm_01_distributional.ipynb) respecto a diseño de matrices. Utilizamos el módulo `preprocessing.py` que implementa dos funciones: `build_cooccurrence_matrix` y `corpus_processor`.La función `corpus_processor` realiza una _tokenización_ de los archivos del corpus. Opcionalmente también realiza dos pasos de preprocesamiento simples: remoción de "palabras vacías" (_stopwords_) y normalización llevando las palabras a minúsculas.La función `build_cooccurrence_matrix` toma documentos ya tokenizados (representados como una lista de palabras) y en base a estos ejecuta el conteo y armado de la matriz de co-ocurrencias, a partir de los parámetros propuestos.Se recomienda leer y tratar de entender las funciones, preguntando ante cualquier duda.<jupyter_code>from preprocessing import build_cooccurrence_matrix, corpus_processor
infoleg_5window_scaled = build_cooccurrence_matrix(
    corpus=corpus_processor("./data/infoleg_text/"),
    window_size=5,
    scale_factor="scaled",
    vocab_size=5000,
    unkown_vector=True
)

infoleg_5window_scaled.to_csv("./data/infoleg_5window_scaled.csv.gz")
infoleg_20window_flat = build_cooccurrence_matrix(
    corpus=corpus_processor("./data/infoleg_text/"),
    window_size=20,
    scale_factor="flat",
    vocab_size=5000,
    unkown_vector=True
)

infoleg_20window_flat.to_csv("./data/infoleg_20window_flat.csv.gz")<jupyter_output><empty_output><jupyter_text>Descarga de los modelosLa creación de la matriz de coocurrencias es lenta, y aunque se puede optimizar y realizar paralelamente, no se busca tener un código extremadamente optimizado sino que es más importante que sea legible y entendible. De todas maneras, si bien la implementación está, no es necesario que hagan el cálculo por su cuenta. Los modelos de InfoLEG están disponibles para descargar. Basta ejecutar la siguiente celda:<jupyter_code>%%bash

mkdir -p ./data/
curl -L -o ./data/infoleg_vsm.tar.bz2 https://cs.famaf.unc.edu.ar/\~ccardellino/resources/infoleg/infoleg_vsm.tar.bz2
tar xvf ./data/infoleg_vsm.tar.bz2 -C ./data
rm -f ./data/infoleg_vsm.tar.bz2<jupyter_output><empty_output><jupyter_text>Carga de los modelosPara cargar un modelo de VSM, se lo hace mediante Pandas. Se tiene que indicar que la primera columna es el índice del dataframe.<jupyter_code>import pandas as pd
infoleg_5window_scaled = pd.read_csv("./data/infoleg_5window_scaled.csv.gz", index_col=0)
infoleg_5window_scaled.head()
infoleg_20window_flat = pd.read_csv("./data/infoleg_20window_flat.csv.gz", index_col=0)
infoleg_20window_flat.head()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07255048616305161, 'fraction_numerical': 0.014771877337322364, 'mean_word_length': 5.383054892601432, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 22, 'https://': 3, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '520622', 'license': 'MIT', 'n_tokens_mistral': 1856, 'n_tokens_neox': 1825, 'n_words': 592, 'path': 'preprocesamiento_corpus.ipynb', 'repo_name': 'PLN-FaMAF/text-mining-2019', 'size': '5361'}