15. Procesamiento Lenguaje Natural (NLP) II#

15.1. Data#

Características de la Data

Una de las primeras cosas necesarias para las tareas de procesamiento del lenguaje natural (NLP) es un corpus. Este corpus deben estar en formato de texto estructurado, como cadenas de caracteres o documentos de texto. Esto puede incluir documentos en formato plano (txt) o formato PDF, documentos HTML, correos electrónicos, publicaciones en redes sociales,entre otros.
Bases de Datos de Corpus para NLP

15.1.1. Ejemplo de descarga de Corpus#

# si no la has intalado pip install nltk 
import nltk
from nltk.downloader import Downloader
nltk.download("book")
[nltk_data] Downloading collection 'book'
[nltk_data]    | 
[nltk_data]    | Downloading package abc to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package abc is already up-to-date!
[nltk_data]    | Downloading package brown to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package brown is already up-to-date!
[nltk_data]    | Downloading package chat80 to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package chat80 is already up-to-date!
[nltk_data]    | Downloading package cmudict to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package cmudict is already up-to-date!
[nltk_data]    | Downloading package conll2000 to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package conll2000 is already up-to-date!
[nltk_data]    | Downloading package conll2002 to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package conll2002 is already up-to-date!
[nltk_data]    | Downloading package dependency_treebank to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package dependency_treebank is already up-to-date!
[nltk_data]    | Downloading package genesis to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package genesis is already up-to-date!
[nltk_data]    | Downloading package gutenberg to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package gutenberg is already up-to-date!
[nltk_data]    | Downloading package ieer to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package ieer is already up-to-date!
[nltk_data]    | Downloading package inaugural to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package inaugural is already up-to-date!
[nltk_data]    | Downloading package movie_reviews to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package movie_reviews is already up-to-date!
[nltk_data]    | Downloading package nps_chat to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package nps_chat is already up-to-date!
[nltk_data]    | Downloading package names to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package names is already up-to-date!
[nltk_data]    | Downloading package ppattach to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package ppattach is already up-to-date!
[nltk_data]    | Downloading package reuters to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package reuters is already up-to-date!
[nltk_data]    | Downloading package senseval to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package senseval is already up-to-date!
[nltk_data]    | Downloading package state_union to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package state_union is already up-to-date!
[nltk_data]    | Downloading package stopwords to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package stopwords is already up-to-date!
[nltk_data]    | Downloading package swadesh to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package swadesh is already up-to-date!
[nltk_data]    | Downloading package timit to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package timit is already up-to-date!
[nltk_data]    | Downloading package treebank to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package treebank is already up-to-date!
[nltk_data]    | Downloading package toolbox to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package toolbox is already up-to-date!
[nltk_data]    | Downloading package udhr to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package udhr is already up-to-date!
[nltk_data]    | Downloading package udhr2 to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package udhr2 is already up-to-date!
[nltk_data]    | Downloading package unicode_samples to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package unicode_samples is already up-to-date!
[nltk_data]    | Downloading package webtext to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package webtext is already up-to-date!
[nltk_data]    | Downloading package wordnet to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package wordnet is already up-to-date!
[nltk_data]    | Downloading package wordnet_ic to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package wordnet_ic is already up-to-date!
[nltk_data]    | Downloading package words to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package words is already up-to-date!
[nltk_data]    | Downloading package maxent_treebank_pos_tagger to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package maxent_treebank_pos_tagger is already up-
[nltk_data]    |       to-date!
[nltk_data]    | Downloading package maxent_ne_chunker to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package maxent_ne_chunker is already up-to-date!
[nltk_data]    | Downloading package universal_tagset to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package universal_tagset is already up-to-date!
[nltk_data]    | Downloading package punkt to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package punkt is already up-to-date!
[nltk_data]    | Downloading package book_grammars to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package book_grammars is already up-to-date!
[nltk_data]    | Downloading package city_database to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package city_database is already up-to-date!
[nltk_data]    | Downloading package tagsets to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package tagsets is already up-to-date!
[nltk_data]    | Downloading package panlex_swadesh to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package panlex_swadesh is already up-to-date!
[nltk_data]    | Downloading package averaged_perceptron_tagger to
[nltk_data]    |     /Users/claudiorojas/nltk_data...
[nltk_data]    |   Package averaged_perceptron_tagger is already up-
[nltk_data]    |       to-date!
[nltk_data]    | 
[nltk_data]  Done downloading collection book
True
from nltk.book import *
*** Introductory Examples for the NLTK Book ***
Loading text1, ..., text9 and sent1, ..., sent9
Type the name of the text or sentence to view it.
Type: 'texts()' or 'sents()' to list the materials.
text1: Moby Dick by Herman Melville 1851
text2: Sense and Sensibility by Jane Austen 1811
text3: The Book of Genesis
text4: Inaugural Address Corpus
text5: Chat Corpus
text6: Monty Python and the Holy Grail
text7: Wall Street Journal
text8: Personals Corpus
text9: The Man Who Was Thursday by G . K . Chesterton 1908
from nltk.book import text3 as text
len(text1)
260819
print(text.name,"\n")
extracto = " ".join(text[:44])
print(extracto)
The Book of Genesis 

In the beginning God created the heaven and the earth . And the earth was without form , and void ; and darkness was upon the face of the deep . And the Spirit of God moved upon the face of the waters .

15.1.2. Ejemplo de Corpus Gutenberg#

import nltk
nltk.corpus.gutenberg.fileids()
['austen-emma.txt',
 'austen-persuasion.txt',
 'austen-sense.txt',
 'bible-kjv.txt',
 'blake-poems.txt',
 'bryant-stories.txt',
 'burgess-busterbrown.txt',
 'carroll-alice.txt',
 'chesterton-ball.txt',
 'chesterton-brown.txt',
 'chesterton-thursday.txt',
 'edgeworth-parents.txt',
 'melville-moby_dick.txt',
 'milton-paradise.txt',
 'shakespeare-caesar.txt',
 'shakespeare-hamlet.txt',
 'shakespeare-macbeth.txt',
 'whitman-leaves.txt']

15.1.3. Ejemplo de descarga del Quijote de la Mancha#

import requests
from bs4 import BeautifulSoup
import nltk
from nltk.corpus import PlaintextCorpusReader

# URL de Project Gutenberg para Don Quijote de la Mancha en español
url = 'https://www.gutenberg.org/ebooks/2000.txt.utf-8'

# Descargar el archivo de texto
response = requests.get(url)
text = response.text

# Guardar el texto en un archivo local
with open('don_quijote.txt', 'w', encoding='utf-8') as f:
    f.write(text)

# Crear un corpus en NLTK con el texto descargado
corpus_root = '.'  # Directorio donde se guarda el archivo de texto
wordlists = PlaintextCorpusReader(corpus_root, 'don_quijote.txt', encoding='utf-8')

# Ejemplo de uso del corpus
print(wordlists.words()[:50])  # Mostrar las primeras 50 palabras del corpus
['The', 'Project', 'Gutenberg', 'eBook', 'of', 'Don', 'Quijote', 'This', 'ebook', 'is', 'for', 'the', 'use', 'of', 'anyone', 'anywhere', 'in', 'the', 'United', 'States', 'and', 'most', 'other', 'parts', 'of', 'the', 'world', 'at', 'no', 'cost', 'and', 'with', 'almost', 'no', 'restrictions', 'whatsoever', '.', 'You', 'may', 'copy', 'it', ',', 'give', 'it', 'away', 'or', 're', '-', 'use', 'it']

15.2. Pre procesamiento del texto#

¿Qué es el Perocesamiento del Corpus o texto?

El preprocesamiento de datos consiste en una serie de pasos, algunos de los cuales pueden o no aplicarse a una tarea específica, pero generalmente se clasifican en las amplias categorías de tokenización, normalización, eliminación de las stopwords y Lematización o Stemming.

15.2.1. Tokenización#

¿Qué es la Tokenización?

Es el proceso de dividir un texto en unidades más pequeñas llamadas "tokens". En el contexto del procesamiento del lenguaje natural, los tokens suelen ser palabras individuales o partes más pequeñas de las palabras, como subpalabras o caracteres. La tokenización es una etapa fundamental en el preprocesamiento de texto antes de realizar análisis de texto, minería de datos o tareas de procesamiento de lenguaje natural, ya que permite descomponer el texto en unidades manejables para su posterior procesamiento.

15.2.1.1. Ejercicio de Tokenización en Inglés#

nltk.download("punkt")
[nltk_data] Downloading package punkt to
[nltk_data]     /Users/claudiorojas/nltk_data...
[nltk_data]   Package punkt is already up-to-date!
True

¿Qué es algoritmo puntk?

Este se utiliza específicamente para la tokenización de oraciones en texto en inglés y otros idiomas. La tokenización de oraciones implica dividir un párrafo o un texto más largo en oraciones individuales. Es un modelo de aprendizaje automático entrenado para identificar los límites de las oraciones en función de patrones lingüísticos y estructurales.
from nltk.tokenize import sent_tokenize, word_tokenize
extracto = """
["Genesis" by Biblia]
In the beginning God created the heaven and the earth . And the earth was without form , and void ; and darkness was upon the face of the deep . And the Spirit of God moved upon the face of the waters ."""

lista_de_frases_0 = sent_tokenize(extracto)
print(lista_de_frases_0,"\n")

lista_de_palabras_0 = word_tokenize(extracto)
print(lista_de_palabras_0)
['["Genesis" by Biblia]\nIn the beginning God created the heaven and the earth .', 'And the earth was without form , and void ; and darkness was upon the face of the deep .', 'And the Spirit of God moved upon the face of the waters .'] 

['[', '``', 'Genesis', "''", 'by', 'Biblia', ']', 'In', 'the', 'beginning', 'God', 'created', 'the', 'heaven', 'and', 'the', 'earth', '.', 'And', 'the', 'earth', 'was', 'without', 'form', ',', 'and', 'void', ';', 'and', 'darkness', 'was', 'upon', 'the', 'face', 'of', 'the', 'deep', '.', 'And', 'the', 'Spirit', 'of', 'God', 'moved', 'upon', 'the', 'face', 'of', 'the', 'waters', '.']
lista_de_palabras_0 = word_tokenize(extracto)
print(lista_de_palabras_0)
['[', '``', 'Genesis', "''", 'by', 'Biblia', ']', 'In', 'the', 'beginning', 'God', 'created', 'the', 'heaven', 'and', 'the', 'earth', '.', 'And', 'the', 'earth', 'was', 'without', 'form', ',', 'and', 'void', ';', 'and', 'darkness', 'was', 'upon', 'the', 'face', 'of', 'the', 'deep', '.', 'And', 'the', 'Spirit', 'of', 'God', 'moved', 'upon', 'the', 'face', 'of', 'the', 'waters', '.']
from nltk.tokenize import sent_tokenize, word_tokenize

poema_ejemplo = """
["I'm nobody! Who are you?" by Emily Dickinson]
I'm nobody! Who are you?
Are you nobody, too?
Then there's a pair of us — don't tell!
They'd banish us, you know.
How dreary to be somebody!
How public, like a frog
To tell your name the livelong day
To an admiring bog!"""

lista_de_frases = sent_tokenize(poema_ejemplo)
print(lista_de_frases,"\n")

lista_de_palabras = word_tokenize(poema_ejemplo)
print(lista_de_palabras[:15])
['\n["I\'m nobody!', 'Who are you?"', "by Emily Dickinson]\nI'm nobody!", 'Who are you?', 'Are you nobody, too?', "Then there's a pair of us — don't tell!", "They'd banish us, you know.", 'How dreary to be somebody!', 'How public, like a frog\nTo tell your name the livelong day\nTo an admiring bog!'] 

['[', '``', 'I', "'m", 'nobody', '!', 'Who', 'are', 'you', '?', "''", 'by', 'Emily', 'Dickinson', ']']
lista_de_palabras = word_tokenize(poema_ejemplo)
print(lista_de_palabras)
['[', '``', 'I', "'m", 'nobody', '!', 'Who', 'are', 'you', '?', "''", 'by', 'Emily', 'Dickinson', ']', 'I', "'m", 'nobody', '!', 'Who', 'are', 'you', '?', 'Are', 'you', 'nobody', ',', 'too', '?', 'Then', 'there', "'s", 'a', 'pair', 'of', 'us', '—', 'do', "n't", 'tell', '!', 'They', "'d", 'banish', 'us', ',', 'you', 'know', '.', 'How', 'dreary', 'to', 'be', 'somebody', '!', 'How', 'public', ',', 'like', 'a', 'frog', 'To', 'tell', 'your', 'name', 'the', 'livelong', 'day', 'To', 'an', 'admiring', 'bog', '!']

15.2.1.2. Ejercicio de Tokenización en español#

from nltk.tokenize import sent_tokenize, word_tokenize

poema_ejemplo_2 = """
["Poema 20" by Pablo Neruda]
Puedo escribir los versos más tristes esta noche.
Escribir, por ejemplo: «La noche está estrellada,
y tiritan, azules, los astros, a lo lejos».
El viento de la noche gira en el cielo y canta.
Puedo escribir los versos más tristes esta noche.
Yo la quise, y a veces ella también me quiso."""

lista_de_frases_2 = sent_tokenize(poema_ejemplo_2)
print(lista_de_frases_2,"\n")

lista_de_palabras_2 = word_tokenize(poema_ejemplo_2)
print(lista_de_palabras_2[:15])
['\n["Poema 20" by Pablo Neruda]\nPuedo escribir los versos más tristes esta noche.', 'Escribir, por ejemplo: «La noche está estrellada,\ny tiritan, azules, los astros, a lo lejos».', 'El viento de la noche gira en el cielo y canta.', 'Puedo escribir los versos más tristes esta noche.', 'Yo la quise, y a veces ella también me quiso.'] 

['[', '``', 'Poema', '20', "''", 'by', 'Pablo', 'Neruda', ']', 'Puedo', 'escribir', 'los', 'versos', 'más', 'tristes']
lista_de_palabras_2 = word_tokenize(poema_ejemplo_2)
print(lista_de_palabras_2)
['[', '``', 'Poema', '20', "''", 'by', 'Pablo', 'Neruda', ']', 'Puedo', 'escribir', 'los', 'versos', 'más', 'tristes', 'esta', 'noche', '.', 'Escribir', ',', 'por', 'ejemplo', ':', '«', 'La', 'noche', 'está', 'estrellada', ',', 'y', 'tiritan', ',', 'azules', ',', 'los', 'astros', ',', 'a', 'lo', 'lejos', '»', '.', 'El', 'viento', 'de', 'la', 'noche', 'gira', 'en', 'el', 'cielo', 'y', 'canta', '.', 'Puedo', 'escribir', 'los', 'versos', 'más', 'tristes', 'esta', 'noche', '.', 'Yo', 'la', 'quise', ',', 'y', 'a', 'veces', 'ella', 'también', 'me', 'quiso', '.']

15.2.2. Normalización#

¿Qué es la Normalización?

Esta coloca todas las palabras en igualdad de condiciones y permite que el procesamiento continúe de manera uniforme. Implica convertir todo el texto al mismo caso (mayúsculas o minúsculas), eliminar puntuaciones, convertir números en sus equivalentes en palabras, entre otras cosas.

15.2.2.1. Ejemplo 1 de Normalización#

import nltk
from nltk.tokenize import word_tokenize
import string

# Texto de ejemplo
texto = """
["Poema 20" by Pablo Neruda]
Puedo escribir los versos más tristes esta noche.
Escribir, por ejemplo: «La noche está estrellada,
y tiritan, azules, los astros, a lo lejos».
El viento de la noche gira en el cielo y canta.
Puedo escribir los versos más tristes esta noche.
Yo la quise, y a veces ella también me quiso."""

# Convertir a minúsculas
texto_miniscula = texto.lower()

# Eliminar puntuación
texto_sin_puntuacion = texto_miniscula.translate(str.maketrans('', '', string.punctuation))

# Tokenización
tokens = word_tokenize(texto_sin_puntuacion)

print("Texto original:")
print(texto)
print("\nTexto normalizado:")
print(texto_sin_puntuacion )
print("\nTokens:")
print(tokens)
Texto original:

["Poema 20" by Pablo Neruda]
Puedo escribir los versos más tristes esta noche.
Escribir, por ejemplo: «La noche está estrellada,
y tiritan, azules, los astros, a lo lejos».
El viento de la noche gira en el cielo y canta.
Puedo escribir los versos más tristes esta noche.
Yo la quise, y a veces ella también me quiso.

Texto normalizado:

poema 20 by pablo neruda
puedo escribir los versos más tristes esta noche
escribir por ejemplo «la noche está estrellada
y tiritan azules los astros a lo lejos»
el viento de la noche gira en el cielo y canta
puedo escribir los versos más tristes esta noche
yo la quise y a veces ella también me quiso

Tokens:
['poema', '20', 'by', 'pablo', 'neruda', 'puedo', 'escribir', 'los', 'versos', 'más', 'tristes', 'esta', 'noche', 'escribir', 'por', 'ejemplo', '«', 'la', 'noche', 'está', 'estrellada', 'y', 'tiritan', 'azules', 'los', 'astros', 'a', 'lo', 'lejos', '»', 'el', 'viento', 'de', 'la', 'noche', 'gira', 'en', 'el', 'cielo', 'y', 'canta', 'puedo', 'escribir', 'los', 'versos', 'más', 'tristes', 'esta', 'noche', 'yo', 'la', 'quise', 'y', 'a', 'veces', 'ella', 'también', 'me', 'quiso']
15.2.2.1.1. Ejercicio 2 de Normalización: lower() vs casefold()#

¿Qué es casefold?

Es una versión más agresiva de lower() lo que significa que convertirá más caracteres a minúsculas y encontrará más coincidencias al comparar dos cadenas si ambas se convierten utilizando el método casefold(). Es de utilidad especialmente cuando se trabaja con diferentes idiomas.
texto_ejemplo = "Mit freundlichen Grüßen" # "Atentamente" en español

print(f"lower: \t\t{texto_ejemplo.lower()}\ncasefold: \t{texto_ejemplo.casefold()}")

# lower() identifica los caracteres ASCII (256)
# casefold() identifica los caracteres UNICODE (143859)
lower: 		mit freundlichen grüßen
casefold: 	mit freundlichen grüssen
from nltk.corpus import stopwords

stop_words = stopwords.words("spanish")

print("Cantidad de stopwords: ", len(stop_words))
print("Por ejemplo: ", stop_words[:20])
print("la" in set(stop_words))
Cantidad de stopwords:  313
Por ejemplo:  ['de', 'la', 'que', 'el', 'en', 'y', 'a', 'los', 'del', 'se', 'las', 'por', 'un', 'para', 'con', 'no', 'una', 'su', 'al', 'lo']
True

15.2.3. Eliminación de las Stopwords#

¿Qué son las Stopwords?

Son palabras de uso común (como "el", "un", "una" o "en") que un motor de búsqueda ha sido programado para ignorar, tanto al indexar entradas para la búsqueda como al recuperarlas como resultado de una consulta de búsqueda.

15.2.3.1. Ejemplo de eliminacion Stopwords en inglés#

nltk.download("stopwords")
[nltk_data] Downloading package stopwords to
[nltk_data]     /Users/claudiorojas/nltk_data...
[nltk_data]   Package stopwords is already up-to-date!
True
from nltk.corpus import stopwords

stop_words = stopwords.words("english")

print("Cantidad de stop words: ", len(stop_words))
print("Por ejemplo: ", stop_words[:10])
print("then" in set(stop_words))
Cantidad de stop words:  179
Por ejemplo:  ['i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', "you're"]
True
# Obtener la lista de stopwords en inglés
stopwords_en = set(stopwords.words('english'))

# Ejemplo de texto de entrada
texto = "This is an example of how to remove stopwords in English."

# Tokenizar el texto en palabras
palabras = texto.split()

# Eliminar las stopwords en inglés
palabras_filtradas = [palabra for palabra in palabras if palabra.lower() not in stopwords_en]

# Reconstruir el texto sin las stopwords
texto_filtrado = ' '.join(palabras_filtradas)

print(texto_filtrado)
example remove stopwords English.

15.2.3.2. Ejemplo de eliminacion Stopwords en español#

# Obtener la lista de stopwords en español
stopwords_es = set(stopwords.words('spanish'))

# Ejemplo de texto de entrada
texto = "Este es un ejemplo de cómo eliminar stopwords en español."

# Tokenizar el texto en palabras
palabras = texto.split()

# Eliminar las stopwords en español
palabras_filtradas = [palabra for palabra in palabras if palabra.lower() not in stopwords_es]

# Reconstruir el texto sin las stopwords
texto_filtrado = ' '.join(palabras_filtradas)

print(texto_filtrado)
ejemplo cómo eliminar stopwords español.

15.2.3.3. Ejemplo utilizando tokenización y removiendo stop words en inglés#

lista_de_frases = sent_tokenize(poema_ejemplo)
frase = lista_de_frases[5]
print(frase)
palabras= word_tokenize(poema_ejemplo)
print(palabras, "\n")

# utilizando un simple for loop
resultado = []
for palabra in palabras:
   if palabra.casefold() not in stop_words:
        resultado.append(palabra)



print(resultado)
Then there's a pair of us — don't tell!
['Then', 'there', "'s", 'a', 'pair', 'of', 'us', '—', 'do', "n't", 'tell', '!'] 

['Then', 'there', "'s", 'pair', 'of', 'us', '—', 'do', "n't", 'tell', '!']

15.2.3.4. Ejemplo utilizando tokenización y removiendo stop words en español#

lista_de_frases_2 = sent_tokenize(poema_ejemplo_2)
frase = lista_de_frases_2[2]
print(frase)
palabras= word_tokenize(lista_de_frases_2[2])
print(palabras, "\n")

# utilizando un simple for loop
resultado = []
for palabra in palabras:
   if palabra.casefold() not in stop_words:
        resultado.append(palabra)


print(resultado)
El viento de la noche gira en el cielo y canta.
['El', 'viento', 'de', 'la', 'noche', 'gira', 'en', 'el', 'cielo', 'y', 'canta', '.'] 

['viento', 'noche', 'gira', 'cielo', 'canta', '.']

15.2.4. Stemming y Lemmatizacion#

15.2.4.1. Stemming#

¿Qué es Stemming?

El stemming es un proceso lingüístico que consiste en la eliminación de sufijos y prefijos de las palabras para reducirlas hasta su raíz o stem. Al eliminar sufijos o prefijos, las palabras de un mismo tema general, como, por ejemplo: corriendo y correra, son cambiadas a “corr”. Generalmente, se emplea para disminuir la complejidad de un texto, facilitando que un software procese y comprenda los patrones de un tema con más claridad.
15.2.4.1.1. Ejemplo de Stemming en inglés#
string_for_stemming = """
The crew of the USS Discovery discovered many discoveries.
Discovering is what explorers do."""

words = word_tokenize(string_for_stemming)

print("Palabras originales: ", words[:10])
Palabras originales:  ['The', 'crew', 'of', 'the', 'USS', 'Discovery', 'discovered', 'many', 'discoveries', '.']
from nltk.stem import PorterStemmer

stemmer = PorterStemmer()

stemmed_words = [stemmer.stem(word) for word in words]

print("Palabras stemmizadas: ", stemmed_words[:10])
Palabras stemmizadas:  ['the', 'crew', 'of', 'the', 'uss', 'discoveri', 'discov', 'mani', 'discoveri', '.']
from nltk.stem.snowball import SnowballStemmer

print(" ".join(SnowballStemmer.languages))
stemmer = SnowballStemmer("english")
# stemmer = SnowballStemmer("english", ignore_stopwords=True) # no stem stopwords

stemmed_words = [stemmer.stem(word) for word in words]

print("Palabras stemmizadas: ", stemmed_words[:10])
arabic danish dutch english finnish french german hungarian italian norwegian porter portuguese romanian russian spanish swedish
Palabras stemmizadas:  ['the', 'crew', 'of', 'the', 'uss', 'discoveri', 'discov', 'mani', 'discoveri', '.']
# El stemmer 'english' es mejor que el stemmer 'porter' original (creado en 1979).

print(SnowballStemmer("english").stem("generously"))
print(SnowballStemmer("porter").stem("generously"))
generous
gener
15.2.4.1.2. Ejemplo de Stemming en español#
import nltk
from nltk.stem.snowball import SnowballStemmer

# Configurar el stemmer para español
stemmer = SnowballStemmer(language='spanish')

# Ejemplo de palabras que deben reducirse al mismo stem
palabra1 = "corriendo"
palabra2 = "correrá"

# Aplicar stemming
stem1 = stemmer.stem(palabra1)
stem2 = stemmer.stem(palabra2)

# Resultados
print(f"Palabra original 1: {palabra1}")
print(f"Stem 1: {stem1}")
print(f"\nPalabra original 2: {palabra2}")
print(f"Stem 2: {stem2}")
Palabra original 1: corriendo
Stem 1: corr

Palabra original 2: correrá
Stem 2: corr

15.2.4.2. Lemmatización#

¿Qué es la Lemmatización?

La lematización en el procesamiento del lenguaje natural (PNL) es el proceso de reducir las palabras inflectadas (o flexionadas) a su forma base, conocida como lema. El lema es la forma canónica de una palabra, que generalmente se encuentra en un diccionario y representa el significado principal de esa palabra. La lematización utiliza un conocimiento más profundo del idioma y aplica reglas lingüísticas complejas para garantizar que el lema obtenido sea una palabra real y tenga significado. Ejemplo: El lema de "corriendo", "correría" y "correrá" es "correr".
15.2.4.2.1. Ejemplo de Lemmatización en inglés#
nltk.download('omw-1.4')
[nltk_data] Downloading package omw-1.4 to
[nltk_data]     C:\Users\Lisandro\AppData\Roaming\nltk_data...
[nltk_data]   Package omw-1.4 is already up-to-date!
True
from nltk.stem.snowball import SnowballStemmer
from nltk.stem import WordNetLemmatizer

stemmer = SnowballStemmer("english")
lemmatizer = WordNetLemmatizer()

print(stemmer.stem("scarves"))
print(lemmatizer.lemmatize("scarves"))

# Al igual que el stemming, la lematización reduce las palabras a su significado principal,
# pero le dará una palabra inglesa completa que tiene sentido por sí misma en lugar de
# un fragmento de una palabra como 'discoveri'.
scarv
scarf
print(lemmatizer.lemmatize("worst"))

# lemmatizar como un adjetivo (recordar POS), por defecto es "n": noun
print(lemmatizer.lemmatize("worst", pos="a"))
worst
bad
15.2.4.2.2. Ejemplo de Lematización en español#
import nltk
from nltk.stem import WordNetLemmatizer
nltk.download('wordnet')

# Configurar lematizador para español
lemmatizer = WordNetLemmatizer()

# Palabras de ejemplo
words = ["corriendo", "correría", "correrá", "mejores", "niños"]

# Lematización
lemmatized_words = [lemmatizer.lemmatize(word, pos='v') for word in words]

# Resultados
for original, lemmatized in zip(words, lemmatized_words):
    print(f"Palabra original: {original} => Lema: {lemmatized}")
[nltk_data] Downloading package wordnet to
[nltk_data]     /Users/claudiorojas/nltk_data...
[nltk_data]   Package wordnet is already up-to-date!
Palabra original: corriendo => Lema: corriendo
Palabra original: correría => Lema: correría
Palabra original: correrá => Lema: correrá
Palabra original: mejores => Lema: mejores
Palabra original: niños => Lema: niños

¿Cuál es la diferencia entre stemming y lemmatización?

El stemming es una técnica de procesamiento de lenguaje natural que se enfoca en reducir las palabras a su raíz básica mediante la eliminación de sufijos y prefijos. Este proceso, conocido como truncamiento, produce formas simplificadas de las palabras, como 'cicl' en lugar de 'ciclista', o 'escri' en vez de 'escribir'. Aunque es eficaz para reducir la complejidad léxica, el stemming a menudo genera raíces que no son palabras reales en el idioma, lo que puede limitar su utilidad en ciertas aplicaciones.
Por otro lado, la lematización es una técnica más sofisticada que utiliza diccionarios y reglas gramaticales para transformar palabras flexionadas a su forma base, o lema. A diferencia del stemming, la lematización tiene en cuenta el contexto lingüístico de una palabra, lo que permite identificar la forma base correcta. Por ejemplo, 'ciclista' se lematizaría a 'ciclista', manteniendo su significado y gramática, mientras que 'escribir', 'escribió' y 'escribiendo' se reducirían correctamente a 'escribir'. Este enfoque más preciso y semánticamente significativo hace que la lematización sea especialmente valiosa para tareas de análisis textual y comprensión del lenguaje natural.