UD03 · Notebook 4 — Primeros pasos con spaCy¶
#importamos todos los módulos necesarios
import spacy
import spacy.cli
#descargamos el modelo pre-entrenado de español (también hay catalan), y tienen diferentes longitudes y precisiones
#este modelo es el más grande y más preciso en español
#spacy.cli.download("es_dep_news_trf")
#nlp = spacy.load("es_dep_news_trf")
#tenemos también es_core_news_sm (español más rápido, pequeño y menos preciso)
spacy.cli.download("es_core_news_sm")
nlp = spacy.load("es_core_news_sm")
#o ca_core_news_sm y ca_core_news_trf (catalan)
import es_core_news_sm
nlp = es_core_news_sm.load()
#lo probamos con una frase
doc = nlp("Esto es una frase.")
print([(w.text, w.pos_) for w in doc])
✔ Download and installation successful You can now load the package via spacy.load('es_core_news_sm') ⚠ Restart to reload dependencies If you are in a Jupyter or Colab notebook, you may need to restart Python in order to load all the package's dependencies. You can do this by selecting the 'Restart kernel' or 'Restart runtime' option. [('Esto', 'PRON'), ('es', 'AUX'), ('una', 'DET'), ('frase', 'NOUN'), ('.', 'PUNCT')]
Preprocesamiento de datos¶
El procesamiento de datos en spaCy es ligeramente más sencillo en spaCy que en NLTK. En este caso se deben importar los modelos entrenados que se han descargado antes y usarlos para obtener los tokens ya tematizados y en minúsculas. Proceso que se puede ver en él siguiente código.
import spacy
text = "Me encanta el contenido del blog de Analytics Lane, los artículos son fantásticos."
#nlp = spacy.load('es_core_news_sm')
doc = nlp(text)
# Eliminación de palabras irrelevantes (stopwords) y signos de puntuación
tokens = [token.lemma_.lower() for token in doc if not token.is_stop and not token.is_punct]
# Reconstrucción del texto preprocesado
preprocessed_text = ' '.join(tokens)
preprocessed_text
'encantar contenido blog analytics lane artículo fantástico'
En este se cargan los modelos mediante la función spacy.load() (si se ha descargado otro se deberá reemplazar el nombre en el parámetro de la función por el que se desee usar). Al modelo importado se le puede pasar la cadena de texto para obtener los tokens (nlp(text)). Posteriormente se filtran aquellos que no son ni stopwords ni elementos de puntuación (not token.is_stop and not token.is_punct) para, en el mismo paso, lematizar y convertir en minúsculas (token.lemma_.lower()). El resultado es el listado de tokens procesados.
Nótese como la herramienta usa como token el infinitivo del verbo en lugar de su versión conjugada (encantar en lugar de encanta). También los términos en plural aparecen en singular (artículo en lugar de artículos). Lo que facilita el análisis de los textos.
Extracción de características¶
En spaCy, la extracción de características también se puede hacer de una forma sencilla. Para lo que se debe iterar sobre los tokens y crear una lista con el conteo de términos. Una posible opción para hacer esto es la que se muestra en el siguiente código de ejemplo.
features = {}
doc = nlp(preprocessed_text)
for token in doc:
if not token.is_stop and not token.is_punct:
if token.lemma_.lower() in features:
features[token.lemma_.lower()] += 1
else:
features[token.lemma_.lower()] = 1
features
{'encantar': 1,
'contenido': 1,
'blog': 1,
'analytics': 1,
'lane': 1,
'artículo': 1,
'fantástico': 1} Lo que genera un diccionario donde la palabra es la clave y el valor es el número de ocurrencias de esta en el texto.
Conjunto de datos de entrenamiento y factorización de los datos¶
Ahora, antes de poder hacer un análisis de sentimientos en español con spaCy es necesario disponer de un conjunto de datos para el entrenamiento. Para lo que se recurre a una traducción del conjunto que se ha utilizado la semana pasada con NLTK.
training_data = [
("Me encanta el contenido del blog de Analytics Lane, los artículos son fantásticos.", "positivo"),
("El código no funciona, me ha dado un error al ejecutarlo.", "negativo"),
("Me encanta este producto.", "positivo"),
("Esta película fue terrible.", "negativo"),
("El clima está agradable hoy.", "positivo"),
("Me siento triste por las noticias.", "negativo"),
("Es solo un libro promedio.", "neutral")
]
print(training_data)
[('Me encanta el contenido del blog de Analytics Lane, los artículos son fantásticos.', 'positivo'), ('El código no funciona, me ha dado un error al ejecutarlo.', 'negativo'), ('Me encanta este producto.', 'positivo'), ('Esta película fue terrible.', 'negativo'), ('El clima está agradable hoy.', 'positivo'), ('Me siento triste por las noticias.', 'negativo'), ('Es solo un libro promedio.', 'neutral')]
Otra cosa que también se puede hacer es crear funciones con las que se factorizan los pasos vistos en las secciones anteriores.
import spacy
def preprocess_text(text):
"""
Realiza el preprocesamiento básico de un texto en idioma español utilizando spaCy.
Args:
text (str): El texto a ser preprocesado.
Returns:
str: El texto preprocesado.
"""
nlp = spacy.load('es_core_news_sm')
doc = nlp(text)
# Eliminación de palabras irrelevantes (stopwords) y signos de puntuación
tokens = [token.lemma_.lower() for token in doc if not token.is_stop and not token.is_punct]
# Reconstrucción del texto preprocesado
preprocessed_text = ' '.join(tokens)
return preprocessed_text
def extract_features(text):
"""
Extrae las características del texto utilizando spaCy y devuelve un diccionario de características.
Args:
text (str): El texto del cual extraer características.
Returns:
dict: Un diccionario que representa las características extraídas del texto.
"""
features = {}
doc = nlp(text)
for token in doc:
if not token.is_stop and not token.is_punct:
if token.lemma_.lower() in features:
features[token.lemma_.lower()] += 1
else:
features[token.lemma_.lower()] = 1
return features
Entrenamiento del modelo¶
Para el análisis de sentimiento uno de los modelos que mejor funciona son Naive Bayes. A diferencia de NLTK, spaCy no cuenta con una implementación propia, pero se puede recurrir a la que existe en Scikit-learn. Así, para entrenar el modelo solamente sería necesario preprocesar los datos, extraer las características y crear un conjunto de entrenamiento para el modelo MultinomialNB(). Pasos que se pueden implementar como se muestra a continuación.
from sklearn.feature_extraction import DictVectorizer
from sklearn.naive_bayes import MultinomialNB
# Preprocesamiento de los datos de entrenamiento
preprocessed_training_data = [(preprocess_text(text), label) for text, label in training_data]
print(preprocessed_training_data)
# Extracción de características de los datos de entrenamiento
training_features = [extract_features(text) for text, _ in preprocessed_training_data]
vectorizer = DictVectorizer(sparse=False)
X_train = vectorizer.fit_transform(training_features)
# Etiquetas de los datos de entrenamiento
y_train = [label for _, label in preprocessed_training_data]
# Entrenamiento del clasificador Naive Bayes
classifier = MultinomialNB()
_ = classifier.fit(X_train, y_train)
[('encantar contenido blog analytics lane artículo fantástico', 'positivo'), ('código funcionar error ejecutar él', 'negativo'), ('encantar producto', 'positivo'), ('película terrible', 'negativo'), ('clima agradable', 'positivo'), ('sentir triste noticia', 'negativo'), ('libro promedio', 'neutral')]
Clasificación de nuevos textos¶
Ahora, una vez entrenado el modelo, se puede usar esta para predecir el sentimiento de los nuevos textos. Simplemente se repiten con los nuevos textos las transformaciones realizadas sobre el conjunto de entrenamiento y el resultado se le pasa al modelo.
# Nuevo texto para clasificar
new_text = "Me encantó mucho del concierto."
# Preprocesamiento del nuevo texto
preprocessed_text = preprocess_text(new_text)
# Extracción de características del nuevo texto
features = extract_features(preprocessed_text)
X_test = vectorizer.transform([features])
# Clasificación del nuevo texto
sentiment = classifier.predict(X_test)
print("Sentimiento:", sentiment[0])
Sentimiento: positivo
Conclusiones¶
spaCy es una librería alternativa NLTK con la que también se puede realizar análisis de sentimientos. Contando con la ventaja de que también se puede hacer en español y otros idiomas gracias a los modelos pre-entrenados que se pueden descargar. Algo que también simplifica el trabajo con la librería. Por eso, en el caso de querer realizar análisis de sentimientos en español, spaCy es una de las opciones que debe tener siempre en cuenta.