<jupyter_start><jupyter_text>Ejemplo: Lematización de textos**Autor:** Unidad de Científicos de Datos (UCD)---Este ejemplo muestra las principales funcionalidades del módulo `lematizacion`, de la librería **ConTexto**. Este módulo permite realizar lematización de textos, una operación que consiste en transormar las palabras de su forma flexionada (plural, femenino, conjugaciones, etc.) a su lema correspondiente, el cual es el representante de todas las formas flexionadas de una misma palabra. Por ejemplo, las palabras niños, niña y niñito tienen todas el mismo lema: niño. Realizar lematización sobre textos puede simplificarlos, al unificar palabras que comparten el mismo lema, y evitando así tener un vocabulario más grande de lo necesario.Para mayor información sobre este módulos y sus funciones, se puede consultar su documentación. --- 1. Definir textos de pruebaEl módulo de lematización de **ConTexto** cuenta con dos lematizadores distintos, cada uno apoyado en una librería de NLP distinta: spaCy y Stanza. En este cuaderno se mostrará el usto de ambas clases, `LematizadorSpacy` y `LematizadorStanza`, y de la función `lematizar_texto`, que puede utilizar cualquiera de los dos lematizadores.En primer lugar, se definen los textos que se utilizarán para correr los ejemplos.<jupyter_code>import time
from contexto.lematizacion import LematizadorSpacy, LematizadorStanza
from contexto.lematizacion import lematizar_texto

# textos de prueba
texto = 'esta es una prueba para ver si las funciones son correctas y funcionan bien. Perritos y gatos van a la casita'
texto_ingles = 'this is a test writing to study if these functions are performing well'
textos = [
    "Esta es una primera entrada en el grupo de textos",
    "El Pibe Valderrama empezó a destacar jugando fútbol desde chiquitin",
    "De los pájaros del monte yo quisiera ser canario",
    "Finalizando esta listica, se incluye una última frase un poquito más larga que las anteriores."
]<jupyter_output><empty_output><jupyter_text>--- 2. Lematización de textos utilizando spaCyLa función `lematizar_texto` se encarga de aplicar lematización a todas las palabras de un texto de entrada. Al realizarse con el lematizador de spaCy, que se utiliza por defecto, el usuario puede elegir el lenguaje y el tamaño del modelo. Para la mayoría de lenguajes hay 3 tamaños de modelos: pequeño ('sm'), mediano ('md') y grande ('lg'). Entre más grande sea el modelo, es posible que tenga un vocabulario más amplio o características adicionales, pero también el archivo del modelo será más grande.**Nota:** La primera vez que se utilice una combinación particular de lenguaje + tamaño, la librería descargará el modelo correspondiente en el computador del usuario. Para poder usar este modelo, se debe reiniciar la sesión de Python y correr la función de nuevo.<jupyter_code># Lematización con librería Spacy 
texto_lematizado = lematizar_texto(texto)
print(texto_lematizado)

print('----')
# Prueba en otro lenguaje (en este caso se detecta automáticamente que es inglés)
lemma_english = lematizar_texto(texto_ingles, 'auto', dim_modelo='small')
print(lemma_english)<jupyter_output>este ser uno probar parir ver si los funcionar ser correcto y funcionar bien perrito y gato ir a lo casita
----
this be a test write to study if these function be perform well<jupyter_text>2.1 Agregar lemas personalizadosLos modelos cuentan con algunos diccionarios de lemas, que utilizan para aplicar la lematización. Así, por ejemplo, el lematizador sabe que para la palabra "iba", su lema debería ser "ir".Es posible que el diccionario del lematizador no contenga todos los casos que nos interesan, por lo que es necesario complementar el lematizador. Esto se puede hacer desde un archivo JSON o desde un diccionario de Python.<jupyter_code># Agregar lemas desde un archivo
archivo_lemmas = 'entrada/dict_lemas.json'
texto_lematizado_v2 = lematizar_texto(texto, dict_lemmas=archivo_lemmas)
print(texto_lematizado_v2)

# Agregar desde un diccionario
segundo_dict = {
    "casita": "casa",
    "casitas": "casa",
    "para": "para",
    "perrito": "perro",
    "perritos": "perro",
    "gatos": "gato"
}
texto_lematizado_v3 = lematizar_texto(texto, dict_lemmas=segundo_dict)
print('------')
print(texto_lematizado_v3)<jupyter_output>este ser uno probar parir ver si los funcionar ser correcto y funcionar bien perro y gato ir a lo casita
------
este ser uno probar parir ver si los funcionar ser correcto y funcionar bien perro y gato ir a lo casa<jupyter_text>2.2 Corrección de varios textos utilizando un solo objeto de la clase `LematizadorSpacy`Si se desea lematizar un conjunto de textos, puede ser más rápido definir un único objeto de clase `LematizadorSpacy`, y pasar este objeto en el parámetro *lematizador* de la función `lematizar_texto`. Al hacer esto puede haber un ahorro de tiempo, pues se evita inicializar un nuevo objeto de clase `LematizadorSpacy` para cada texto. Este ahorro de tiempo será mayor a medida que sean más los textos que se desean lematizar.A continuación se muestra una comparación de tiempos para dos opciones:1. Lematizar una lista de textos, aplicando la función `lematizar_texto` a cada uno sin ninguna otra consideración.2. Definir un objeto de clase `LematizadorSpacy` y utilizarlo para lematizar la misma lista de textos.<jupyter_code># Opción 1: se inicializa el lematizador en cada texto
tic = time.time()
for t in textos:
    print(lematizar_texto(t))

tiempo_1 = time.time() - tic

# Opción 2: se utiliza solo un lematizador para todos los textos
print('--------------------')
tic = time.time()
lematizador = LematizadorSpacy('es')
for t in textos:
    print(lematizar_texto(t, lematizador=lematizador))

tiempo_2 = time.time() - tic

print('\n***************\n')
print('Tiempo con opción 1: {} segundos\n'.format(tiempo_1))
print('Tiempo con opción 2: {} segundos\n'.format(tiempo_2))<jupyter_output>este ser uno primero entrar en el grupo de texto
el pibe valderrama empezar a destacar jugar fútbol desde chiquitin
de lo pájaro del montar yo querer ser canario
finalizar este listica se incluir uno último frase uno poquito más largo que los anterior
--------------------
este ser uno primero entrar en el grupo de texto
el pibe valderrama empezar a destacar jugar fútbol desde chiquitin
de lo pájaro del montar yo querer ser canario
finalizar este listica se incluir uno último frase uno poquito más largo que los anterior

***************

Tiempo con opción 1: 10.844398021697998 segundos

Tiempo con opción 2: 2.4355220794677734 segundos<jupyter_text>--- 3. Lematización de textos utilizando StanzaEl parámetro *libreria* de la función `lematizar_texto` permite elegir 'stanza', para utilizar esta librería. se encarga de aplicar lematización a todas las palabras de un texto de entrada. Si se define *liberia='stanza'*, la función utilizará el lematizador de la clase `LematizadorStanza`. La primera vez que se seleccione un modelo de un lenguaje determinado, la función descargará el modelo correspondiente en el computador del usuario. Este proceso puede durar algunos minutos, dependiendo de la conexión a internet.Es importante recalcar que para poder utilizar el `LematizadorStanza` es necesario tener los paquetes **torch, torhvision y stanza** instalados, que no vienen en la versión de **ConTexto** instalable a través de pip. Para mayor información sobre esto, se puede consultar la documentación de instalación de ConTexto.<jupyter_code># Lematización con librería Stanza ###
texto_lematizado = lematizar_texto(texto, libreria='stanza')
print(texto_lematizado)

# Prueba en otro lenguaje
lemma_english = lematizar_texto(texto_ingles, lenguaje='ingles', libreria='stanza')
print('------')
print(lemma_english)<jupyter_output>este ser uno prueba para ver si el función ser correcto y funcionar bien perrito y gato ir a el casita
------
this be a test writing to study if these function be perform well<jupyter_text>3.1 Agregar lemas personalizadosAl igual que en el caso de spaCy, el `LematizadorStanza` permite añadir o modificar lemas, utilizando un archivo JSON o un diccionario de Python. Esto se hace con la función `modificar_lemmas`, y se puede utilizar el parámetro *archivo_salida* para  determinar dónde se quiere guardar el modelo resultante. De esta manera, este modelo puede ser luego cargado a un objeto de clase `LematizadorStanza` para seguirlo utilizando o modificando. Para cargar un modelo guardado previamente, es necesario utilizar el parámetro *modelo_lemas*, al definir el objeto lematizador.<jupyter_code>## Utilizar un archivo JSON al momento de lematizar
archivo_lemmas = 'entrada/dict_lemas.json'
texto_lematizado_v2 = lematizar_texto(texto,libreria='stanza',dict_lemmas=archivo_lemmas)
print(texto_lematizado_v2)
print('------')

## Modificar los lemas utilizando un diccionario
segundo_dict = {
    "chiquitin": "chico",
    'valderrama': 'valderrama',
    'listica': 'lista'
}

# Inicializar lematizador para lenguaje español
lematizador = LematizadorStanza('es')
print(lematizador.lematizar(textos[1]))
# Modificar lemas y guardar el modelo resultante
lematizador.modificar_lemmas(dict_lemmas=segundo_dict, archivo_salida='salida/modelo_lemas_stanza.pt')
# Lemarizar de nuevo el mismo texto, después de la modificación
print(lematizador.lematizar(textos[1]))<jupyter_output>este ser uno prueba para ver si el función ser correcto y funcionar bien perro y gato ir a el casita
------
el pibe valderramo empezar a destacar jugar fútbol desde chiquitin
el pibe valderrama empezar a destacar jugar fútbol desde chico<jupyter_text>3.2 Corrección de varios textos utilizando un solo objeto de la clase `LematizadorStanza`Si se desea lematizar un conjunto de textos, puede ser más rápido definir un único objeto de clase `LematizadorStanza`, y pasar este objeto en el parámetro *lematizador* de la función `lematizar_texto`. Al hacer esto puede haber un ahorro de tiempo, pues se evita inicializar un nuevo objeto de clase `LematizadorStanza` para cada texto. Este ahorro de tiempo será mayor a medida que sean más los textos que se desean lematizar.A continuación se muestra una comparación de tiempos para dos opciones:1. Lematizar una lista de textos, aplicando la función `lematizar_texto` a cada uno sin ninguna otra consideración.2. Definir un objeto de clase `LematizadorStanza` y utilizarlo para lematizar la misma lista de textos.<jupyter_code># Opción 1: se inicializa el lematizador en cada texto
tic = time.time()
for t in textos:
    print(lematizar_texto(t, libreria='stanza', modelo_lemas='salida/modelo_lemas_stanza.pt'))

tiempo_1 = time.time() - tic

# Opción 2: se utiliza solo un lematizador para todos los textos
print('--------------------')
tic = time.time()
# Se carga el modelo guardado previamente en el ejemplo
lematizador = LematizadorStanza('es', modelo_lemas='salida/modelo_lemas_stanza.pt')
for t in textos:
    print(lematizar_texto(t, lematizador=lematizador))

tiempo_2 = time.time() - tic

print('\n***************\n')
print(f'Tiempo con opción 1: {tiempo_1} segundos\n')
print(f'Tiempo con opción 2: {tiempo_2} segundos\n')<jupyter_output>este ser uno primero entrada en el grupo de texto
el pibe valderrama empezar a destacar jugar fútbol desde chico
de el pájaro del monte yo querer ser canario
finalizar este lista él incluir uno último frase uno poquito más largo que el anterior
--------------------
este ser uno primero entrada en el grupo de texto
el pibe valderrama empezar a destacar jugar fútbol desde chico
de el pájaro del monte yo querer ser canario
finalizar este lista él incluir uno último frase uno poquito más largo que el anterior

***************

Tiempo con opción 1: 3.8512158393859863 segundos

Tiempo con opción 2: 1.04310941696167 segundos
{'fraction_non_alphanumeric': 0.07177563720057967, 'fraction_numerical': 0.009376864717415395, 'mean_word_length': 5.148846960167715, 'pattern_counts': {'":': 7, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '410389', 'license': 'X11', 'n_tokens_mistral': 4002, 'n_tokens_neox': 3969, 'n_words': 1530, 'path': 'ejemplos/05_Lematización de textos.ipynb', 'repo_name': 'sergiomora03/ConTexto', 'size': '11731'}