Tokenización y Vocabulario en TorchText para DBpedia
Resumen
¿Cómo iniciar la tokenización de nuestros textos con Torch Text?
En la ciencia de datos y el procesamiento del lenguaje natural, la tokenización es un paso esencial para convertir textos en datos que una máquina pueda utilizar. En esta clase, te guiaré para comprender cómo comenzar con esta tarea usando Torch Text, específicamente aplicando tokenización a los textos de DBpedia.
¿Qué es Torch Text y cómo se utiliza?
Torch Text es una poderosa biblioteca de PyTorch destinada a facilitar el manejo y la transformación de datos textuales. Nos permite tokenizar textos, crear vocabularios y más. Empezaremos examinando un dataset para familiarizarnos con su estructura antes de avanzar al procesamiento.
Carga inicial del dataset: Utilizaremos un train iter que actuará como iterador sobre los datos ya importados de DBpedia. Esto nos permite visualizar cómo son los textos en bruto.
Uso del iterador: Con el comando next, podemos obtener el siguiente elemento del iterador, lo que nos permite observar los datos de nuestro dataset de manera secuencial.
train_iter =...sample_text =next(train_iter)
¿Cuál es la importancia de la tokenización?
La tokenización convierte largas oraciones o fragmentos textuales en piezas más pequeñas. Esto es crucial para que las máquinas puedan trabajar con texto, transformándolo en números y facilitando así la comprensión y el procesamiento automatizado.
Importar herramientas necesarias: Usaremos GetTokenizer de Torch Text para la tokenización. Esta función nos proporciona una variedad de tokenizadores predefinidos, incluyendo BasicEnglish.
Elegir el tokenizador correcto: Torch Text permite utilizar diferentes tokenizadores. Aunque en este caso usamos BasicEnglish, otros como spaCy o HuggingFace también son viables dependiendo de nuestras necesidades.
from torchtext.data.utils import get_tokenizer
tokenizador = getTokenizer('basic_english')
¿Cómo se crea y utiliza un vocabulario?
Un vocabulario traduce los tokens en números. Esto permite a las máquinas interpretar el texto de manera eficiente.
Crear un iterador: Necesitamos un iterador de nuestros datos para pasar cada texto por el tokenizador.
Generar tokens: Construimos una función yieldTokens que toma un iterador de textos y devuelve los tokens procesados.
Construcción del vocabulario: Utilizamos la función BuildVocabFromIterator para crear un mapa de tokens a números enteros, considerando también los tokens desconocidos.
from torchtext.vocab import build_vocab_from_iterator
defyield_tokens(data_iter):for _, text in data_iter:yield tokenizador(text)vocabulario = build_vocab_from_iterator(yield_tokens(train_iter), specials=["<unk>"])vocabulario.set_default_index(vocabulario["<unk>"])
¿Cómo desarrollar funciones para procesar datos eficientemente?
El uso de funciones ayuda a simplificar el proceso de conversión de texto en números. Dos funciones clave son textoPipeline y labelpipeline:
Pipeline de texto: Transformación de texto en una secuencia de tokens que luego pasan a números usando un vocabulario.
Pipeline de etiquetado: Toma una etiqueta numérica y la ajusta para empezar desde cero.
Cuando ejecutamos estas herramientas en texto de ejemplo como "Hello, I am Omar", obtenemos una lista de números enteros que representan cada palabra en el vocabulario. Así, logramos que los datos textuales sean aptos para el análisis y modelado.
El viaje hacia el procesamiento y análisis de datos nunca termina. ¡Anímate a seguir explorando el potencial de estas técnicas y herramientas que ofrece Torch Text!
Funciona bien, en mi caso puse la declaración de la clase DBpedia en una celda, la ejecute con los cambios que recomiendas y el resto funcionó OK
Si tienen algún problema con esta solución, intenten bajar la versión de Python y/o torchtext a la que se utiliza en el video.
Con la 3.9.7 de Python y la 0.15.1 de torchtext me funcionó a mi finalmente.
Tuve la duda de cómo funcionaba el tokenizer + vocabulario y traigo mis conclusiones.
El tokenizer simplemente separa las palabras en tokens, y el algoritmo que usemos (en este caso basic_english) determinará qué caracteres tokenizará y que limpiezas y convenciones llevará a cabo (agregar espacios a las puntuaciones, transformar los saltos de linea en espacios sencillos y demás limpiezas) y retornará un array gigante con los cada palabra tokenizada.
El vocab (o vocabulario) por otra parte es especial. El proceso para determinar qué valor numérico pertenece a cada token es directamente proporcional a su frecuencia de aparición. Entre más aparezca un token en un dataset (también llamado text corpus) menor valor tendrá, por eso los conectores suelen tener valores tan bajos.
La razón por la que debemos agregar el <unk> en el vocab es porque únicamente hemos creado los valores de los tokens disponibles en el text corpus, por lo que, si en alguna inferencia usamos texto que no contiene un token válido, debemos tener un mecanismo para encapsularlo.
si tienen el error
ImportError: cannot import name ‘DILL_AVAILABLE’ from ‘torch.utils.data.datapipes.utils.common’
Se actualizo la libreria no funciona, me pide los datos de train pero no encuentro la forma de solucionarlo :C
Gracias crack!
Estuve horas y horas en está clase porque como saben lass librerías se actualizan , así mismo deberían actualizarse los cursos para evitar esos problemas , pero básicamente hay varios problemas al intentar ejecutar eso hoy en día, y es que las versiones en la clase son ya antiguas , para que podamos cargar el torchtext y los datos estos tienen que estar alineados con las versiones
Ejemplo mío utilizado , descargar las versiones compatibles entre si
Importante reiniciar la sesión en el google colab para que lo cargue
De esa manera puedo usar torchtext con la version compatible a mi version de torch y también el torch data que es importante para poder cargar los datos cuando las versiones están por encima de la 0.17 , de esa manera ya pueden seguir exactamente los pasos una vez puedan hacer eso
También otro punto es que torch text muchos de los datasets son bajados de google drive lo cual a veces las urls cambian por lo que recomendaría probar con otros dataset no con el de la clase
Mi caso
from torchtext.datasets import AG_NEWS
otro dataset que pude usar con facilidad para continuar con el proyecto
Hola @Juan Tienes razon, torch text datasets han cambiado sus url :
<p>
The error indicates that the DBpedia dataset failed to download because the Google Drive link being used is not a direct download link. This usually happens when the download mechanism expects a specific 'content-disposition' header from Google Drive, which is missing with the current link. To resolve this, you might need to manually download the dataset from Google Drive or retry, as Google Drive download links can sometimes be temperamental for programmatic access.
</p>
Yo l oitnetado muchas veces pero no puede obtenerlo en colab, asi que itente con el que vosotros propones, AG_NEWS ese funciona bien, llevare el resto de la clase con el.
PD: Gracias.
No he logrado hacer que funcione el Script de Colab, me indica que ha diferencia de version entre torch y torchtext. De hecho éste ultimo aparece como "depricated".... hay algun nuevo Script?
Gracias Juan Pablo, logre avanzar un poco, pero al momento de tokenizar me empezo a dar errores...."vocab = build_vocab_from_iterator(yield_tokens(train_iter), specials=["<unk>"])...
Tengo algunas duda, para entender mejor como funciona la tokenizacion y el vocabulario.
La tokenizacion es la que separa palabras y el vocabulario el que la un número único? Porque entonces le ponemos al tokenizador que use ingles, el separa por detectar que tipo de palabras? Y de ser el caso que separa por sentido de palabra y relación, cual tokenizador de palabras en español hasta mal escritas recomiendan?
Dando mi opinión a tus inquietudes:
Efectivamente tokenizar es poder entender que cada elemento de una oración es un objeto con sentido. Puedes tokenizar a nivel letra o a nivel palabra. Si bien la intuición nos dice que la forma más sencilla sería identificar cada palabra porque esta separada por un espacio " " esto no es necesariamente cierto.
En una oración puedes tener palabras que tengan sentido o que ni siquiera existan:
Hola cómo estás?
aer fu aksa te?
Un buen tokenizador solo te devolvería los elementos que relamente son palabras.
Una vez que de tu corpus (todas las palabras disponibles de tu dataset) obtuviste tus tokens puedes asignarles un número que represente a la palabra, de esta forma "discretizas" las palabras.
lo ponemos en inglés porque DBPEDIA está en inglés y pese a que "amarillo" es un token, en inglés no está definida la palabra entonces pasaría a ser "unk"
Lidiar con palabras mal escritas es mucho más complejo, tendrías que tu mismo crear tu tokenizador haciendo splits por espacio, pero tendrías un vocab enorme lleno de variantes de la misma palabra y normalmente quieres evitar eso, porque todas esas variantes en realidad significan lo mismo. Normalmente otro proceso muy importante que se hace es aplicar lemmatization o stemming que básicamente buscan llevar a una expresión común diferentes palabras. Por ejemplo:
gatos
gatas
gatitos
gatitas
Todas tienen como raiz "gato" todas esas palabras NO serían tratadas como entedes diferentes sino como "gato" y todas compartirían el mismo identificador númerico (este proceso de stemming no fue tratado en esta clase, pero es un concepto bastante útil)
Te recomiendo chechar Spacy ES.
Cual es la razón principl de crear los pipelines? Tampoco me quedo muy claro, en el ciclo fro no habiamos creado ya el vocabulario?
Hasta donde he podido entender tu pregunta, me parece que estas mezclando los conceptos de tokenización y creación del vocabulario.
El primero es solamente separar las palabras basandote en el idioma inglés como referencia, el segundo es asignarles una represtación númerica de acuerdo al corpus con el que fue entrenado (en nuestro caso DBpedia)
de esta manera el texto_pipeline es en si misma una función que hace 2 cosas por nosotros:
Recibe un parámetro X que es un texto y lo pasa por la función tokenizador (básicamente separa las palabras)
Después de haber tokenizado la oración obtiene su representación númerica con vocab
De esta manera en un solo pipeline entra una oración y sale una representación númerica del mismo.
PD en este cacho del código:
defyield_tokens(data_iter):for _, texto in data_iter:yield tokenizador(texto)
NO creaste el vocabulario en sí mismo, solo hiciste un yield a una oración específica con su versión tokenizada, es hasta:
El procesamiento de datos, especialmente en tareas de procesamiento de lenguaje natural (NLP), implica pasos como la tokenización y la creación de vocabularios. Aquí te explico ambos conceptos y cómo se implementan, particularmente en el contexto de PyTorch.
### 1. Tokenización
La **tokenización** es el proceso de dividir un texto en unidades más pequeñas llamadas "tokens". Estos pueden ser palabras, subpalabras o caracteres. La tokenización permite que los modelos entiendan el texto en un formato que pueden procesar.
Existen diferentes enfoques de tokenización:
- **Tokenización por palabras**: Divide el texto en palabras.
- **Tokenización por subpalabras**: Utiliza algoritmos como Byte Pair Encoding (BPE) para dividir palabras en subunidades, lo que es útil para manejar palabras desconocidas y reducir el vocabulario.
- **Tokenización por caracteres**: Cada carácter se convierte en un token, lo que puede ser útil para ciertos tipos de modelos.
### Ejemplo de Tokenización en PyTorch
Aquí hay un ejemplo básico de cómo realizar la tokenización utilizando torchtext:
import torch
from torchtext.data.utils import get\_tokenizer
\# Texto de ejemplo
text ="Hola, esto es un ejemplo de tokenización."
\# Crear un tokenizador
tokenizer = get\_tokenizer("basic\_english")
\# Tokenizar el texto
tokens = tokenizer(text)print(tokens)
### 2. Creación de Vocabulario
La **creación de vocabulario** implica construir un conjunto de todos los tokens únicos que aparecen en tu conjunto de datos. Esto es fundamental porque el modelo necesita mapear cada token a un número entero (índice) que puede utilizar durante el entrenamiento.
Los vocabularios pueden ser simples o pueden incluir mapeos adicionales, como las frecuencias de palabras.
### Ejemplo de Creación de Vocabulario en PyTorch
A continuación, se muestra un ejemplo de cómo crear un vocabulario a partir de los tokens:
from collections import Counter
from torchtext.vocab import Vocab
\# Contar la frecuencia de los tokens
counter = Counter(tokens)
\# Crear el vocabulario
vocab = Vocab(counter)
\# Ver el vocabulario
print(vocab.stoi)# Muestra el índice de cada tokenprint(vocab.itos)# Muestra el token correspondiente a cada índice
### Integración en el Entrenamiento del Modelo
Una vez que tienes los tokens y el vocabulario, puedes convertir tus textos en secuencias de índices y alimentar estos índices a tu modelo de PyTorch para el entrenamiento.
### Ejemplo Completo
Aquí hay un flujo de trabajo más completo que incluye la tokenización y la creación de vocabulario:
import torch
from torchtext.data.utils import get\_tokenizer
from collections import Counter
from torchtext.vocab import Vocab
\# Texto de ejemplo
corpus = \[  "Hola, esto es un ejemplo de tokenización.",  "Este es otro ejemplo para crear vocabulario."]
\# Crear un tokenizador
tokenizer = get\_tokenizer("basic\_english")
\# Tokenizar y contar la frecuencia de tokens
tokens = \[]for line in corpus:  tokens.extend(tokenizer(line))
\# Crear el vocabulario
counter = Counter(tokens)vocab = Vocab(counter)
\# Convertir texto a índices
text\_indices = \[\[vocab\[token]for token in tokenizer(line)]for line in corpus]
\# Mostrar los resultados
print("Vocabulario:", vocab.stoi)print("Índices del texto:", text\_indices)
### Conclusión
La tokenización y la creación de vocabulario son pasos críticos en el procesamiento de datos para modelos de NLP. Usar bibliotecas como torchtext simplifica mucho estos procesos, permitiendo concentrarse en el diseño y entrenamiento de modelos en lugar de preocuparse por el preprocesamiento de datos.
Les qiuiero compartir un video que me explico de una manera muy clara el concepto
Si no les funciona ninguna de las otras soluciones que estaban en los comentarios para solucionar el problema con el dataset, lo que hice fue crear otro ambiente con python 3.9 e instalar la version de torchtext 0.15.1.
No necesariamente debe ser la 3.9, pero era la que tenia a la mano.
¿Dónde estan las archivos de recursos de la clase ?
mmm en la nueva interfaz que lanzaron, mmm debajo del video y del nombre del curso, hay dos pestañas, temario y Recursos, en recursos puedes encontrar los recursoso de la clase 🤓