0% encontró este documento útil (0 votos)
154 vistas

Análisis de Sentimientos Con Python (Parte 1)

Este documento presenta un tutorial para realizar análisis de sentimiento en reseñas de películas en Python. Describe los pasos para descargar y limpiar datos de reseñas de IMDb, vectorizar el texto en datos numéricos, entrenar un clasificador de regresión logística, y evaluar su precisión. El tutorial logra una precisión del 88% en la clasificación de reseñas como positivas o negativas.

Cargado por

Andrea Romo
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
154 vistas

Análisis de Sentimientos Con Python (Parte 1)

Este documento presenta un tutorial para realizar análisis de sentimiento en reseñas de películas en Python. Describe los pasos para descargar y limpiar datos de reseñas de IMDb, vectorizar el texto en datos numéricos, entrenar un clasificador de regresión logística, y evaluar su precisión. El tutorial logra una precisión del 88% en la clasificación de reseñas como positivas o negativas.

Cargado por

Andrea Romo
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 5

Análisis de Sentimiento con Python

El análisis de sentimientos es una tarea muy común en la Programación Neurolingüística


(PNL) que los científicos de datos deben realizar. Les presentamos a continuación una
guía para la creación de un clasificador de películas en Python. La segunda parte de este
tutorial se centrará en una serie de mejoras para el calificador.
RESUMEN DE DATOS
Para este análisis usaremos un conjunto de datos de 50.000 reseñas de películas tomadas
de IMDb. Los datos fueron compilados por Andrew Maas y se pueden encontrar en el
siguiente enlace: Revisiones de IMDb.
Los datos se dividen de manera uniforme con 25.000 comentarios destinados para el
entrenamiento y 25.000 para testear el clasificador. Además, cada conjunto tiene 12.500
comentarios positivos y 12.500 negativos.
IMDb permite a los usuarios calificar las películas en una escala de 1 al 10. Para etiquetar
estas reseñas, el curador de los datos etiqueta con menos o igual de 4 estrellas como
negativo y mayor o igual de 7 estrellas como positivo. Las reseñas con 5 o 6 estrellas
quedan fuera.
PASOS 1: DESCARGAR Y COMBINAR CRÍTICAS DE PELÍCULAS
Si aún no lo ha hecho, vaya a Revisiones de IMDb y de clic en “Large Movie Review Dataset
v1.0”. Una vez descargado, tendrá un archivo llamado aclImdb_v1.tar.gz en su carpeta
de descargas.
Atajo: Si desea ir directamente al análisis de datos y no está muy cómodo manejando el
terminal, se ha colocado un archivo .tar del directorio final, que genera este paso en el
siguiente enlace: Merged Movie Data. Puede descomprimir él .tar, de lo contrario puede
usar el siguiente comando en el terminar para descomprimir el archivo gunzip -c
movie_data.tar.gz | tar xopf —.
DESEMPACAR Y FUSIONAR
Siga los siguientes pasos o ejecute el script de Shell (Preprocessing Script).
1. Mover el archivo .tar al directorio donde desea almacenar estos datos.
2. Abra una ventana de terminal e ingresar al directorio donde se encuentre el
aclImdb_v1.tar.gz con el comando cd.
3. Usar el siguiente comando: gunzip -c aclImdb_v1.tar.gz | tar xopf -
4. Usar el siguiente comando: cd aclImdb && mkdir movie_data
5. Usar el siguiente comando: for split in train test; do for sentiment in pos neg; do
for file in $split/$sentiment/*; do cat $file >> movie_data/full_${split}.txt; echo
>> movie_data/full_${split}.txt; done; done; done;
PASO 2: LEER EN PYTHON
Para los desean realizar este tutorial, solo necesitaremos que nuestras reseñas, estén en
una lista de Python. Asegúrese de escribir correctamente en open, el directorio en donde
colocará los datos de películas.

1 reviews_train = []
2 for line in open('../data/movie_data/full_train.txt', 'r'):
3 reviews_train.append(line.strip())
4 reviews_test = []
5 for line in open('../data/movie_data/full_test.txt', 'r'):
6 reviews_test.append(line.strip())

PASO 3: LIMPIEZA Y PREPROCESO


El texto en bruto es bastante desordenado para las reseñas, así que antes de realizar
cualquier análisis necesitamos hacer una limpieza de los datos. Aquí se muestra el
siguiente ejemplo:
ANTES

"This isn't the comedic Robin Williams, nor is it the quirky/insane Robin Williams of
recent thriller fame. This is a hybrid of the classic drama without over-dramatization,
mixed with Robin's new love of the thriller. But this isn't a thriller, per se. This is more
a mystery/suspense vehicle through which Williams attempts to locate a sick boy and
his keeper.<br /><br />Also starring Sandra Oh and Rory Culkin, this Suspense Drama
plays pretty much like a news report, until William's character gets close to achieving
his goal.<br /><br />I must say that I was highly entertained, though this movie fails to
teach, guide, inspect, or amuse. It felt more like I was watching a guy (Williams), as he
was actually performing the actions, from a third person perspective. In other words,
it felt real, and I was able to subscribe to the premise of the story.<br /><br />All in all,
it's worth a watch, though it's definitely not Friday/Saturday night fare.<br /><br />It
rates a 7.7/10 from...<br /><br />the Fiend :."

Nota: Comprender y poder usar expresiones regulares es un requisito previo para realizar
cualquier tarea de procesamiento de lenguaje natural. Si no está familiarizado con ello,
quizás comience con el siguiente tutorial: Regex Tutorial.
DESPÚES

"this isnt the comedic robin williams nor is it the quirky insane robin williams of recent
thriller fame this is a hybrid of the classic drama without over dramatization mixed with
robins new love of the thriller but this isnt a thriller per se this is more a mystery
suspense vehicle through which williams attempts to locate a sick boy and his keeper
also starring sandra oh and rory culkin this suspense drama plays pretty much like a
news report until williams character gets close to achieving his goal i must say that i
was highly entertained though this movie fails to teach guide inspect or amuse it felt
more like i was watching a guy williams as he was actually performing the actions from
a third person perspective in other words it felt real and i was able to subscribe to the
premise of the story all in all its worth a watch though its definitely not friday saturday
night fare it rates a from the fiend"

Nota: hay muchas formas diferentes y más sofisticadas para realizar limpieza de datos en
texto, que probablemente produzcan mejores resultados que los realizados en este
tutorial. La parte 1 de este tutorial está centrado en realizar la limpieza de los datos lo
más simple posible.

VECTORIZACIÓN
Para que los datos tengan sentido para nuestro algoritmo de aprendizaje automático,
necesitaremos convertir cada reseña a una representación numérica, lo que llamamos
vectorización.

La forma más simple para vectorizar estos datos es crear una matriz muy grande con una
columna para cada palabra única en su corpus (donde corpus son todos los 50.000
comentarios). Luego transformamos cada reseña en una fila que contenga 0 y 1, donde
1 significa que la palabra en el corpus correspondiente a esa columna y aparece en una
reseña. Dicho esto, cada fila de la matriz será muy díspersa (en su mayoría ceros). Este
proceso también se conoce como hot encoding.

1 from sklearn.feature_extraction.text import CountVectorizer


2 cv = CountVectorizer(binary=True)
3 cv.fit(reviews_train_clean)
4 X = cv.transform(reviews_train_clean)
5 X_test = cv.transform(reviews_test_clean)

PASO 4: CONSTRUIR CLASIFICADOR


Ahora que hemos transformado nuestro conjunto de datos en una forma adecuada para
el modelado, podemos comenzar a construir un clasificador. La regresión logística es un
buen modelo de referencia que podemos usar por varios motivos:

1. Son fáciles de interpretar


2. Los modelos lineales tienden a funcionar bien en conjunto de datos dispersos
como este.
3. Aprenden muy rápido en comparación a otros algoritmos.
Para mantener las cosas simples, solo nos preocuparemos por el hiper-parámetro C, que
ajusta la regularización.

Nota: Las etiquetas que usamos serán los mismas para el entrenamiento y las pruebas
porque ambos conjuntos de datos están estructurados de la misma manera, donde los
primeros 12.500 son positivos y los últimos 12.500 son negativos.
1 from sklearn.linear_model import LogisticRegression
2 from sklearn.metrics import accuracy_score
3 from sklearn.model_selection import train_test_split
4
5 target = [1 if i < 12500 else 0 for i in range(25000)]

6 X_train, X_val, y_train, y_val = train_test_split(


7 X, target, train_size = 0.75
8 )
9
10 for c in [0.01, 0.05, 0.25, 0.5, 1]:
11 lr = LogisticRegression(C=c)
12 lr.fit(X_train, y_train)
13 print ("Accuracy for C=%s: %s"
14 % (c, accuracy_score(y_val, lr.predict(X_val))))
15
16 # Accuracy for C=0.01: 0.87472
17 # Accuracy for C=0.05: 0.88368
18 # Accuracy for C=0.25: 0.88016
19 # Accuracy for C=0.5: 0.87808
20 # Accuracy for C=1: 0.87648
21

Parece que el valor de C que nos da la mayor precisión es 0.05.


ENTRENAMIENTO MODELO FINAL
Ahora que hemos encontrado el valor óptimo para C, deberíamos entrenar el modelo
utilizando todo el conjunto de datos destinados para el entrenamiento, para
posteriormente evaluar nuestra precisión en las 25.000 reseñas.

1 final_model = LogisticRegression(C=0.05)
2 final_model.fit(X, target)
3 print ("Final Accuracy: %s"% accuracy_score(target, final_model.predict(X_test)))

Como una prueba de validez, revisaremos las 5 palabras más discriminatorias para las
reseñas tanto positivas como negativas. Haremos esto observando los coeficientes más
grandes y pequeños, respectivamente.

1 feature_to_coef = {
2 word: coef for word, coef in zip(
3 cv.get_feature_names(), final_model.coef_[0]
4 )
5 }

6 for best_positive in sorted(


7 feature_to_coef.items(),
8 key=lambda x: x[1],
9 reverse=True)[:5]:
10 print (best_positive)
11
12 # ('excellent', 0.9288812418118644)
13 # ('perfect', 0.7934641227980576)
14 # ('great', 0.675040909917553)
15 # ('amazing', 0.6160398142631545)
16 # ('superb', 0.6063967799425831)
17
18 for best_negative in sorted(
19 feature_to_coef.items(),
20 key=lambda x: x[1])[:5]:
21 print (best_negative)
22
23 # ('worst', -1.367978497228895)
24 # ('waste', -1.1684451288279047)
25 # ('awful', -1.0277001734353677)
26 # ('poorly', -0.8748317895742782)
27 # ('boring', -0.8587249740682945)
28

Finalmente tendremos un clasificador muy simple con una muy buena precisión.

También podría gustarte