Análisis de Sentimiento con Cassandra y Python
Análisis de Sentimiento con Cassandra y Python
Python
M EMORIA
Enrique Villarreal
Adrián Asensio
Curso 2016-2017
1 de junio de 2017
Hoy en día, dos de los conceptos más populares en la industria son el big data y la ciencia de
los datos. En éste proyecto, nos mojaremos los pies un poco en ambos conceptos, apoyándonos
del SGBD NoSQL Apache Cassandra y Python para realizar un breve análisis de sentimiento de
twits recogidos mediante la API de Twitter.
Palabras clave: big data, data science, nosql, cassandra, python, twitter
Abstract
These days, two of the most popular buzzwords in IT are big data, and data science. In this
project, we will get our feet wet in both these concepts, using the NoSQL DBMS Apache Cassan-
dra and Python to perform sentiment analysis on tweets collected by using the Twitter API.
2
Índice
1. Introducción 1
1.1. Contexto y justificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3. Metodología . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.4. Características técnicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.5. Planificación del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5.1. Lista de tareas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5.2. Diagrama Gantt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.6. Descripción de los capítulos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.7. Formato de éste documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
7. Análisis de sentimiento 30
7.1. Clasificación estadística . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
7.1.1. Clasificador Bayesiano ingenuo . . . . . . . . . . . . . . . . . . . . . . . . . 30
8. Conclusiones 32
8.1. Objetivos del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
8.2. Próximos pasos del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
ÍNDICE ÍNDICE
Glosario 37
Referencias 37
4
Índice de figuras
1. Base de datos de grafos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2. Flujo de trabajo del científico de datos . . . . . . . . . . . . . . . . . . . . . . . . . 10
3. Dataframe.head() en Jupyter Notebook . . . . . . . . . . . . . . . . . . . . . . . . 11
4. Características de un dataset “limpio” . . . . . . . . . . . . . . . . . . . . . . . . . 12
5. Análisis explorativo con pandas, parte 1 . . . . . . . . . . . . . . . . . . . . . . . . 13
6. Temperaturas media diaria del río Fisher a su paso cerca de Dallas en el año 1990 14
7. Gráficos de ambas variables independientes contra la dependiente . . . . . . . . . 16
8. Recta de regresión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
9. Arquitectura del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
10. Secuencia de eventos - análisis de sentimiento . . . . . . . . . . . . . . . . . . . . 20
11. Estructura de un espacio de claves . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
12. Estructura de una fila . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
13. Particiones de fila única . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
14. Particionado compuesto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
15. Resultados del algoritmo Porter en algunas palabras . . . . . . . . . . . . . . . . . 28
16. Fórmula del teorema de Bayes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
17. Fórmula del teorema de Bayes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
ÍNDICE DE CUADROS ÍNDICE DE CUADROS
Índice de cuadros
1. Métodos de Pandas para leer datos . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2. My caption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3. Dataset derretido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4. Tipos de datos CQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
6
1 INTRODUCCIÓN
1. Introducción
1.1. Contexto y justificación
Las bases de datos relacionales llevan con nosotros desde hace más de 40 años. Están
basadas en el modelo relacional (Codd, 1970), en el que los datos se representan en tuplas,
agrupadas en relaciones, que por lo general, representan entidades. Por tanto, almacenan datos
estructurados, y resultan ideales en situaciones en las cuales el modelo de los datos está rígi-
damente definido.
De todas maneras, la mayor parte de la información que se genera a diario en Internet (pista:
mucha), no se ajusta a niguna estructura, y por tanto, no puede ser almacenada tal cual en sis-
temas con esquemas definidos. En respuesta a ello, y al rápido aumento en la cantidad de datos a
procesar, surgieron las bases de datos NoSQL. Al no usar el tradicional modelo relacional, éstas
resultan mucho más adecuadas para manejar datos sin ningún tipo de organización o estructura.
Otro de los conceptos al que va enfocado el proyecto es el de ciencia de los datos, posible-
mente el último “no va más” en el mercado. Hasta ha sido clasificado por Glassdoor como el
mejor trabajo en América a inicios de 2016 1 . Uno de los motivos por los cuales decidimos ex-
plorar éste concepto en el proyecto es el hecho de que aunque lleva ya tiempo establecido, aún
sigue sin un currículo estandarizado, o una definición concreta a la que acogerse.
1.2. Objetivos
Los objetivos principales del proyecto son:
1.3. Metodología
El proyecto se dividirá en dos partes: la primera consistirá en un estudio de las bases de
datos NoSQL, concretamente Apache Cassandra, comparando brevemente su modelo de datos
con el modelo relacional. Además, exploraremos el concepto de ciencia de los datos, una nueva
profesión que combina diferentes disciplinas, desde la programación hasta las matemáticas y
la estadística, centrada en en la solución de problemas / obtención de conocimiento a partir de
información.
La segunda parte consistirá en utilizar lo aprendido en la primera parte para implementar
un sistema que aproveche las aptitudes de Cassandra para el big data y el análisis de datos.
A ése fin, utilizaremos la API Streaming de Twitter para obtener twits y almacenarlos en Apache
Cassandra, sobre los cuales luego utilizaremos Python para realizar análisis de sentimiento sobre
los twits.
1
1.5 Planificación del proyecto 1 INTRODUCCIÓN
Librerías:
• Datastax Cassandra driver for Python
• Get-Old-Tweets
• Pandas
• Natural Language Toolkit (NLTK)
Presentación: Reveal.js
Aplicaciones auxiliares:
• Jupyter Notebook
Nota: Se irá actualizando ésta lista a medida que se van descubriendo nuevas herramientas
y librerías.
Tarea Predecesora
1 Redactar estudio
1.1 Describir brevemente las bases de datos NoSQL
1.2 Estudiar Apache Cassandra: su modelo de datos, y sus casos de uso ideales 1.1
1.3 Realizar una comparativa con las bases de datos relacionales 1.2
1.4 Definir el concepto de ciencia de los datos
1.5 Entender la metodología del científico de datos 1.4
2 Implementación del proyecto 1
2.1 Estudio de algoritmos de clasificado y selección del mismo.
2.2 Diseño e implementación de la base de datos 2.1
2.3 Introducción a los algoritmos de clasificado 2.2
2.4 Implementación del programa para popular la base de datos 2.3
2.5 Análisis de los datos 2.4
2 Redacción de la memoria
2
1.5 Planificación del proyecto 1 INTRODUCCIÓN
2017
03 04
07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 01 02 03 04 05 06 07 08
Introducción
Apache Cassandra
Comparativa
Introducción
Flujo de trabajo
Algoritmos de clasificado
Entrega estudio
3
1.6 Descripción de los capítulos 1 INTRODUCCIÓN
2017
04 05
08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 01 02 03 04 05 06 07 08 09 10 11 12
Implementación
Selección de algoritmo
Implementación prog.
Análisis de sentimiento
Preparación del dataset
Entrega implementación
2017
05 06
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 01 02
4
1.7 Formato de éste documento 1 INTRODUCCIÓN
Bloque de comandos
comandos a ser introducidos por el usuario en un intérprete de comandos
1 for i in range(1,10):
2 print("Código fuente")
Aviso
Información a tener en cuenta.
¡Aviso importante!
Información importante a tener en cuenta.
5
2 ESTADO DEL ARTE: BASES DE DATOS NOSQL
Teorema de CAP
En los sistemas distribuidos, el teorema de CAP, formulado por Eric Brewer, dice lo siguiente:
Teorema CAP. Es imposible para un sistema distribuido ofrecer más de dos de las siguientes
garantías al mismo tiempo: consistencia, disponibilidad y tolerancia de particiones.
En el contexto del teorema, cada una de las garantías se define tal que:
Consistencia: Cada lectura recibe como respuesta la escritura más reciente, o un error.
Disponibilidad: Cada petición recibe una respuesta no-errónea, sin garantizar que con-
tenga la escritura más reciente.
6
2.2 Tipos de bases de datos NoSQL 2 ESTADO DEL ARTE: BASES DE DATOS NOSQL
7
2.2 Tipos de bases de datos NoSQL 2 ESTADO DEL ARTE: BASES DE DATOS NOSQL
y así.
2. Las aristas, también llamadas relaciones, son las líneas que conectan los nodos, repre-
sentando las relaciones entre ellos.
En contraste a las bases de datos relacionales, éstas almacenan directamente las relaciones
entre nodos, por lo que, en teoría, las consultas que deban enlazar información son más veloces
en bases de datos de grafos, ya que un SGBD relacional debe realizar una join en dos tablas
diferentes. Ésta eficiencia se va acentuando conforme la complejidad de la consulta aumenta:
una base de datos orientada a grafos sólo debe seguir las aristas a partir del nodo inicial.
Algunos ejemplos de bases de datos orientadas a grafos son AllegroGraph, Neo4j y Openlink
Virtuoso.
8
3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
3.1. Introducción
Las bases de datos NoSQL no son lo único que ha traído el “Big Bang” de la información en
Internet. De la misma manera que se hace evidente la necesidad de poder almacenar toda ésta
nueva información de manera eficiente, también lo hace la necesidad de aprovechar y utilizar és-
tos datos de manera eficiente. A éstos efectos, se ha ido gestando una nueva disciplina dedicada
al estudio de nuevos métodos para generar información útil y ofrecer valor a partir de datos de
cualquier manera, a la que hoy se conoce como “ciencia de los datos”, o en inglés, data science.
El primer uso del término data a 1966 cuando Peter Naur utilizó en 1966 porque no le gustaba
el nombre de “ciencias de la computación”, y consideraba este último más apropiado. Incluso
hoy en día, aunque el término lleve usándose en su forma actual más de veinte años, no existe
ninguna definición formal sobre qué entraña exactamente, sino que simplemente diferentes in-
vestigadores han aportado su opinión en qué quiere decir el término. Chikio Hayashi (Hayashi,
1998) la definió como un concepto para unificar estadística, análisis de datos y métodos rela-
cionados, y Zhu et. al (Yanyong y Yun, 2011) la definieron de forma elegante como una nueva
ciencia cuyo objeto de estudio son los datos.
Una vez ha definido la pregunta a responder, es hora de obtener los datos. Éstos pueden
venir de una infinidad de fuentes o formatos de fichero: desde CSV, hojas de cálculo de Excel o
LibreOffice y ficheros en formato JSON / XML, a bases de datos relacionales y NoSQL. Resulta
imperativo que un científico de datos conozca de dónde puede sacar la información, y sepa
recogerla toda en un mismo entorno.
La siguiente tabla muestra la lista de métodos de los que dispone Pandas (una librería para
Python que provee estructuras de datos y herramientas para facilitar el análisis) para leer fuentes
de datos, y generar un DataFrame (una estructura de datos tabular):
Obviamente, existen muchos más formatos en los que podemo encontrar los datos, a parte
de los que Pandas puede leer. En ese caso, tocará recurrir a otras herramientas con las que
podamos interactuar con el servicio en cuestión, para posteriormente transferir los datos a un
DataFrame, o cualquier otra estructura que deseemos utilizar.
Un concepto interesante que queda a medias entre éste proceso de minería y el pre-procesado,
es el uso de bases de datos intermedias. Es decir, el diseño de una base de datos adicional,
dónde almacenaremos los datos después de la limpieza, pre-procesado y validación. De éste
9
3.2 Flujo de trabajo 3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
modo, se garantiza la calidad de los datos que utilizaremos en nuestro análisis, y la organización
/ mantenimiento de los mismos se hace más eficiente
10
3.2 Flujo de trabajo 3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
Básicamente, las preguntas que deberíamos tratar de responder con éste análisis inicial son
las siguientes:
En caso de que en nuestro dataset nos encontremos con variables para las que directamente
no exista una observación, existen varias técnicas que podemos utilizar para tratar los registros.
Las dos primeras que describiremos, trabajan de forma destructiva, es decir, borrando datos:
¡Cuidado!
Al borrar / ignorar la informacion faltante, éstos métodos pueden introducir imparcialidad
estadística.
2
11
3.2 Flujo de trabajo 3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
La otra manera de tratarlos recibe el nombre de imputación, y consiste en sustituir los valores
nulos. Para ésto, también disponemos de varias técnicas:
1. Para variables contínuas, podemos sustituir valores nulos por la media aritmética de los
valores no nulos.
2. Para variables categóricas, podemos sustituir valores nulos por la moda de los valores no
nulos. El valor que más veces se dé, será el que utilizaremos en la imputación.
Tidy data
Aunque lo ideal sería que cada dataset que encontráramos viniera ya en un estado ideal
para ponernos a analizar su contenido, esto generalmente no es así. Hadley Wickham utiliza el
término tidy data (Wickham, 2014), para referirse a cualquier dataset que reúne las siguientes
características:
Según Wickham ésta es la tercera forma normal de Codd, con las restricciones extrapoladas a
lenguaje estadístico, y enfocada a un único dataset / tabla, en lugar de datasets interconectados
en una base de datos relacional.
En pandas, podemos utilizar los métodos Pandas.pivot() y Pandas.melt() para realizar las
tareas de “apilado” y “derretido”, que Wickham describe en el mismo artículo:
1 import pandas as pd
2 df = pd.DataFrame({’Id’: {0: ’David’, 1: ’b’, 2: ’c’},
3 ’Lotería’: {0: ’Juan’, 1: 3, 2: 5},
4 ’Sorteo iPad’: {0: ’Sergio’, 1: 4, 2: 6}})
Cuadro 2: My caption
Observando el dataset, aunque sea de ejemplo, podemos ver que incumple uno de los tres
principios del tidy data, que cada columna represente una variable. En éste caso, cada una de-
scribe un valor. Entonces, para transformar el dataset, en un formato más cómodo de trabajar
para el análisis, utilizaremos melt():
1 import pandas as pd
2
3 pd.melt(df, id_vars=[’Id’], value_vars=[’Lotería’, ’Sorteo iPad’],
12
3.2 Flujo de trabajo 3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
4 var_name=’Concurso’, value_name=’VecesGanado’)
1 df[df[’Sorteo’] == ’Lotería’]
2 df[df[’VecesGanado’] > 5]
1
2 DataFrame.shape # Devuelve las dimensiones (Filas x Columnas)
3 DataFrame.columns # Devuelve las columnas (features)
4 DataFrame.info # Devuelve la cantidad de valores no-nulos en cada
columna
5 DataFrame.describe() # Agregado de estadísticas como la media, min / max,
etc...
6
7 DataFrame[’VariableCategórica’].unique() # Devuelve la lista de valores que
toma la variable.
Llegados a éste punto, en el que hemos identificado la variable en cuestión como categórica,
es necesario cambiarle el tipo a la misma de cara a la representación que Pandas hace de la
misma:
1 df[’VariableCategórica’] = df[’VariableCategórica’].astype(’category’)
13
3.2 Flujo de trabajo 3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
1 df[’VariableCategórica’].value_counts()
1 import pandas as pd
2 import numpy as np
3 import matplotlib.pyplot as plt
4 import matplotlib
5 %matplotlib inline # Necesario para que Jupyter muestre las figuras en la misma
página
6 matplotlib.style.use(’ggplot’)
Antes de proseguir, es importante destacar los dos últimos parámetros que le hemos pasado
a (read_csv): (parse_dates) y (index_col). En conjunto, éstos harán que el primer campo del
dataset, que es la fecha, actúe como índice, permitiéndonos hacer cosas como la siguiente:
Figura 6: Temperaturas media diaria del río Fisher a su paso cerca de Dallas en el año 1990
3.2.6. Modelado
Un modelo estadístico es una clase específica de modelo matemático, una manera formal de
describir sistemas mediante conceptos matemáticos.
Generalmente, un modelo estadístico implica dos tipos de variables: dependientes y explica-
tivas:
14
3.2 Flujo de trabajo 3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
Variable dependiente: se dice de aquella que queremos estudiar o predecir. Suele ser
aquella que se representa en el eje de las Y.
Variable explicativa: También llamadas independientes, son aquellas en las que nos apoy-
amos para describir las variables dependientes.
Existen infinidad de modelos estadísticos que tienen en cuenta tanto el tipo de las variables,
como el número de éstas. Uno de los más simples de entender y implementar es la regresión
lineal, empleada para estudiar la relación de dependencia entre una variable dependiente Y ,
una o más variables independientes Xi , y un término aleatorio ϵ. Si se utiliza una única variable
independiente X, hablamos de una regresión linear simple.
Yi = β0 + βi Xi + ϵi (1)
Dónde:
Ŷ es el valor a predecir
β es la pendiente de la recta
A es el punto de intersección en el eje de las Y.
x ∗ y − xy
β = rs (2)
(x)2 − x2
A = My − bMx (3)
1 import pandas as pd
2 import numpy as np
3
4 import matplotlib
5 import matplotlib.pyplot as plt
6
7 from sklearn import linear_model, model_selection
8 from sklearn.metrics import mean_squared_error
9 %matplotlib inline
10 matplotlib.style.use(’ggplot’)
1 df = pd.read_csv("data/monthlySpending.csv")
2 df.info()
15
3.2 Flujo de trabajo 3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
1 # Gráfico izquierdo
2 plt.scatter(df[’M_INC’], y)
3 plt.title("Gasto mensual vs ingresos mensuales")
4 plt.xlabel("Ingresos mensuales")
5 plt.ylabel("Gasto mensual")
6
7 # Gráfico derecho
8 plt.scatter(df[’M_TRP’], y)
9 plt.title("Gasto mensual vs viajes mensuales")
10 plt.xlabel("Viajes realizados")
11 plt.ylabel("Gasto mensual")
(a) Gasto mensual vs ingresos mensuales (b) Gasto mensual vs viajes mensuales
En el siguiente bloque definimos nuestras variables, tanto dependientes (el gasto mensual),
como independientes (el número de viajes, o los ingresos).
1 y = df[’M_SPEND’]
2 X = df[’M_TRP’]
1 linearRegression = linear_model.LinearRegression()
2
3 # Validación cruzada
4 X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y,
5 test_size = 0.33)
6
7 linearRegression.fit(X_train, y_train)
Validación cruzada
16
3.2 Flujo de trabajo 3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
Cada punto se aleja de media en 2077 unidades de la línea de mejor ajuste (Root mean
squared error )
Variancia
El coeficiente de determinación, también escrito como R2 , indica la proporción de la vari-
ancia en la variable dependiente que es predecible de la variable independiente. En otras
palabras, estima cuán bien la recta de regresión se ajusta a los datos reales. El valor va de
0 a 1, donde un 1 indica un ajuste perfecto.
Una vez verificado el modelo, podemos visualizar la recta de regresión junto a los datapoints
con el siguiente bloque de código:
1 plt.scatter(X, y)
2
3 # Línea de regresión
4 plt.plot(X, np.poly1d(np.polyfit(X, y, 1))(X), color=’blue’)
5 plt.xlabel(’Monthly trips’)
6 plt.xlabel(’Monthly spending)
17
3.2 Flujo de trabajo 3 ESTADO DEL ARTE: CIENCIA DE LOS DATOS
18
4 ESTADO DEL ARTE: ARQUITECTURA DEL PROYECTO
1. En primer lugar, un programa en Python recogerá los twits acorde a diferentes criterios,
y los depositará en Apache Cassandra. Cada tabla estará modelada correspondiendo al
criterio por el que se recogieron los twits: por ejemplo, podemos tener una tabla llama-
da tweets_by_region, en los que irán twits que se obtuvieron consultando por la región
geográfica en concreto.
2. El segundo bloque de la pipeline interactuará con Apache Cassandra, procesando los twits,
y obteniendo un resultado en base a las especificaciones del usuario: evolución del sen-
timiento a lo largo de una franja de tiempo, por zona geográfica, demografía de los usuarios
de Twitter, etc... Una vez procesados los twits, el resultado se almacenará en una base de
datos PostgreSQL, para un posterior visionado más sencillo.
La selección de criterios, se realizará mediante una aplicación web en Django.
3. El tercero y final bloque de la pipeline consistirá en una aplicación web desarrollada en
Django, en la cual se observarán los resultados del análisis, obtenidos directamente de la
base de datos en PostgreSQL.
Originalmente, queríamos realizar ésta tarea con la librería tweepy, que interactúa directa-
mente con las API de Twitter para obtener los datos. Nos hemos visto obligados a optar por otro
proyecto, por limitaciones con las mismas:
La API Streaming va recogiendo y mostrando twits a la que van sucediendo. Ésto es ideal
para conexiones persistentes, y podría ser utilizado en caso de que decidamos ofrecer
análisis de sentimiento en tiempo real.
19
4.2 Características técnicas 4 ESTADO DEL ARTE: ARQUITECTURA DEL PROYECTO
La API REST expone varios endpoints para recibir twits en base a varios criterios. El único
problema con ésta API es que por lo general, no devuelve twits más viejos de una semana,
lo cual nos deja un dataset bastante pobre con el que trabajar.
Ésto nos ha llevado a utilizar el siguiente proyecto como mecanismo para obtener los twits:
GetOldTweets-python. Funciona aprovechando el mecanismo real mediante el que Twitter de-
vuelve los resultados de la búsqueda en el navegador: mediante un cursor y respuestas JSON.
Ya que está utilizando una licencia MIT, tenemos libertad absoluta para coger el código, y ajus-
tarlo a las necesidades del proyecto.
Realmente, ya que la única “clase” que acabemos escribiendo nosotros sea el tokenizador,
debido a pruebas no-satisfactorias con algunos existentes, no podemos crear un diagrama de
clases al uso.
Éste programa primero se conectará a Apache Cassandra, y devolverá un DataFrame de
pandas con los resultados de la consulta. Una vez hecho ésto, se tokenizará, y con las features
resultantes, se utilizará un modelo estadístico ya entrenado para predecir si el twit en cuestión es
negativo o positivo.
El modelo a utilizar en el proyecto, será un clasificador bayesiano ingenuo. Son una familia
de clasificadores probabilísticos 3 basados en la aplicación del teorema de Bayes con una fuerte
asunción de independencia (de ahí el apelativo de ingenuo) entre las características.
20
5 IMPLEMENTACIÓN: APACHE CASSANDRA
Java 8 o superior
Para usar cqlsh, Python 2.7 o superior
En términos de hardware 4 , se recomienda:
• 4 GB de RAM mínimo en entornos virtualizados (EC2 Large)
• Cpu de 8 núcleos en servidores físicos, para entornos virtualizados se recomienda
cualquiera que soporte CPU bursting.
• DISCO
Añadiendo el repositorio
echo "deb http://debian.datastax.com/community stable main" | sudo
tee -a /etc/apt/sources.list.d/cassandra.sources.list
Añadiendo la clave
curl -L http://debian.datastax.com/debian/repo_key | sudo apt-key
add
3. Cuando ya esté instalado, sería buena idea arrancarlo y habilitarlo en cada reinicio del
sistema:
Habilitando servicio
systemctl start cassandra
4 https://wiki.apache.org/cassandra/CassandraHardware
21
5.4 Modelo de datos de Apache Cassandra (API
5 CQL)
IMPLEMENTACIÓN: APACHE CASSANDRA
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 127.0.0.1 222.14 KB 256 100.0 % 2a0b7fa9-23c6-40d3-83a4-
e6c06e2f5736 rack1
1. El factor de replicación especifica el número de nodos que recibirán copias de los mismos
datos.
2. La estrategia de localización de réplicas describe de qué manera se distribuyen las répli-
cas de datos. Existen dos a utilizar, dependiendo de cuántos datacenters consista nuestro
clúster:
22
5.4 Modelo de datos de Apache Cassandra (API
5 CQL)
IMPLEMENTACIÓN: APACHE CASSANDRA
3. Las familias de columnas son contenedores de colecciones de filas, cada una conte-
nienendo columnas ordenadas. Las familias de columnas son análogas a las tablas de una
base de datos relacional, en cierto modo.
23
5.4 Modelo de datos de Apache Cassandra (API
5 CQL)
IMPLEMENTACIÓN: APACHE CASSANDRA
Las claves de fila, no tienen por qué ser únicas. De la misma manera que una clave primaria
compuesta en un RDBMS identifica un registro por un par de valores, una clave de partición
compuesta funciona de la misma manera:
24
5.5 Diseño de las tablas 5 IMPLEMENTACIÓN: APACHE CASSANDRA
La figura también introduce otro concepto, el de clave de agrupación (en inglés, clustering
key). Ésta determina la ordenación de los datos dentro de la partición. En el ejemplo, la clave de
particionado compuesta es (album_title, year), mientras que la de agrupación es num_bef.
Mientras que en un SGBD relacional modelamos la base de datos para que sea normalizada
y minimizar información duplicada, en Apache Cassandra, existen dos reglas / principios a tener
en cuenta a la hora de diseñar las tablas:
1. Repartir la información equitativamente por todo el clúster: el caso ideal es que cada no-
do tuviera aproximadamente la misma cantidad de datos. Recordando lo explicado previa-
mente, ésto lo conseguimos mediante una buena clave de particionado.
2. Minimizar el número de particiones leídas: al hacer una consulta, interesa leer del mínimo
de particiones posibles. La razón es que se realizan comandos separados a cada nodo, por
cada partición que leemos, lo que incurre en mayor overhead y latencia.
El problema, es que estos dos principios entran en conflicto. Al repartir la informació por el
clúster, aumentamos el número de particiones en las que los datos recaen. La respuesta a éste
dilema es un tanto cliché: hay que balancear ambos requerimentos.
25
5.5 Diseño de las tablas 5 IMPLEMENTACIÓN: APACHE CASSANDRA
Antes de ponernos a crear las tablas, debemos crear el keyspace. Ya que sólo tendremos un
nodo en el clúster, emplearemos la SimpleStrategy, y un factor de replicación de 1:
En nuestro proyecto, se nos pueden ocurrir diferentes criterios por los que nos interesaría
realizar una consulta:
Todos los twits de una misma cuenta
Todos los twits que contengan un hashtag concreto
Todos los twits que mencionen una cuenta
Teniendo en cuenta el principio de optimización de consultas, podemos crear las tablas tal
que:
La workaround que hemos pensado, viola el segundo principio ya que es posible que lea
muchas particiones, pero conserva la capacidad de consultar por parte de la lista:
26
5.5 Diseño de las tablas 5 IMPLEMENTACIÓN: APACHE CASSANDRA
27
6 PROCESADO DEL LENGUAJE NATURAL
6.1. Sintaxis
La sintaxis se define como la parte de la gramática que estudia la generación de frases, y las
reglas que se aplican. En éste contexto, algunas de las tareas que podemos aplicar son:
Stemming y lematización
La lematización y el stemming son ambos procesos en los que se reducen formas derivadas
de una palabra, a una raíz que puede no ser una raíz real en el caso del stemming, y un lema
real en el caso de la lematización.
En el contexto de la clasificación de texto, ambos son un proceso clave, considerando que
las características en nuestro caso, son las palabras. Dependiendo del tamaño de nuestro con-
junto de entrenamiento, puede ser conveniente normalizar éstas palabras para pulir un poco los
resultadso
El algoritmo de stemming mejor conocido, es el algoritmo Porter. Funciona mediante detec-
ción de los sufijos de las palabras, y eliminándolos:
killing → kill
killed → kill
disappointment → disappoint
disappointing → disappoint
loved → love
loving → love
La lematización funciona similar, pero con una diferencia: obtendremos siempre palabras (o
lemas, mejor dicho) reales, mientras que el stemming puede devolver términos inexistentes.
El proceso para lematizar unas palabras con NLTK es el siguiente:
Fijémonos en una parte interesante: cuando hemos lematizado stemmed y good, por defecto
nos han devuelto la misma palabra: Eso se debe a que algunas palabras pueden funcionar como
más de una categoría gramatical. Es aquí donde entra en juego el etiquetado gramatical, otro
proceso en el cuál se trata de determinar la función sintáctica de cada palabra.
28
6.1 Sintaxis 6 PROCESADO DEL LENGUAJE NATURAL
6.1.1. Semántica
Reconocimiento de entidades nombradas
Mejor conocido por sus siglas en inglés (NER, named entity recognition), tiene como obje-
tivo detectar y clasificar entidades con nombre propio, dentro de categorías predefinidas como
personas, organizaciones, monedas, etc...
Por ejemplo, en el el texto “Javier se gastó 25 euros en Zara”, el resultado sería Javier
_[PERSONA] se gastó 25 euros _[MONEDA] en Zara_[ORGANIZACIÓN].
En NLTK, el proceso de reconocimiento de entidades nombradas es bastante sencillo:
29
7 ANÁLISIS DE SENTIMIENTO
7. Análisis de sentimiento
El análisis de sentimiento se refiere al procesado de lenguaje natural en el ámbito de iden-
tificar información subjetiva de un texto. En su versión más elemental, y la que llevaremos a
cabo en este proyecto, determinaremos la polaridad de un twit, dicho en otras palabras, si tiene
significado / connotación negativa o positiva.
Obviamente, el análisis de sentimiento no para ahí, si no que un nivel por encima podríamos
detectar el estado emocional del autor.
Por su simplicitud, y popularidad como método base para la categorización de texto, em-
plearemos el clasificador bayesiano ingenuo para éste proyecto.
Dónde:
Dónde:
5 El hecho de que un ordenador aprenda sin ser programado explícitamente
6 Ver glosario
30
7.1 Clasificación estadística 7 ANÁLISIS DE SENTIMIENTO
1
2 import TwitterSentimentAnalysis.TwitterTokenizer
3 import TwitterSentimentAnalysis.data_processing as dp
4 import nltk
5 import pickle
6 from nltk.tokenize import word_tokenize
7 from nltk.corpus import stopwords
8
9 df_train, df_test = dp.load_data()
10
11 df_train = df_train.replace(’"’, "’", regex=True)
12 df_train = df_train.replace(’<-+’, "", regex=True)
13
14 df_test = df_test.replace(’"’, "’", regex=True)
15 df_test = df_test.replace(’<-+’, "", regex=True)
16
17 df_train[’SentimentText’] = df_train[’SentimentText’].map(lambda x: x.strip())
18 df_test[’SentimentText’] = df_test[’SentimentText’].map(lambda x: x.strip())
19
20 all_words = dp.get_tweets_words(df_train)
21
22 stop_words = set(stopwords.words(’english’))
23 features = dp.get_word_features(all_words)
24 filtered_features = [w for w in all_words if not w in stop_words]
25
26 train_tweets = dp.get_tweet_and_sentiment(df_train)
27 training_set = nltk.classify.apply_features(extract_features, train_tweets)
28
29 classifier = nltk.NaiveBayesClassifier.train(training_set)
30
31 print(classifier.show_most_informative_features(100))
31
8 CONCLUSIONES
8. Conclusiones
8.1. Objetivos del proyecto
Al principio del proyecto, nos marcamos los siguientes objetivos:
1. Estudiar y conocer las bases de datos NoSQL, en concreto Apache Cassandra
1.1. Identificar los casos ideales para su uso.
2. Entender el diseño y modelado de datos en Apache Cassandra.
3. Almacenar Twits en Apache Cassandra en base a ciertos criterios de búsqueda. hagan
referencia a un hashtag.
4. Entender y familiarizarse con el flujo de trabajo del científico de datos.
4.1. Realizar análisis de sentimiento de los twits obtenidos mediante Python.
Creemos que podemos considerar explorados, a mayor o menor medida, la mayoría de los
objetivos marcados. Si bien, por razones de empleo, el tiempo que le hemos podido emplear
al proyecto ha sido bastante bajo. Por ésta razón, creemos que el proyecto no ha cumplido los
objetivos a un nivel totalmente satisfactorio, y que se puede profundizar en muchos de las tareas,
si bien consideramos que los conocimientos adquiridos y herramientas trabajadas durante el
proyecto, nos serán de gran utilidad en el futuro.
Personalmente (Enrique) el análisis de datos y data warehousing son dos disciplinas que
recientemente han despertado mi interés. En mi nuevo trabajo, muchos de los conceptos que
hemos tratado aquí aparecen de vez en cuando, por lo que considero que lo aprendido en éste
proyecto me ayudará a crecer profesionalmente, y a introducirme en conceptos que tarde o tem-
prano acabaré encontrándome en mi carrera.
32
9 ANEXO: ESTRUCTURA Y INSTALACIÓN DEL PROYECTO
Projecte
data
twitter-sentiment-dataset.csv
environment.yml
figures
notebooks
ProjecteFinal-Python.ipynb
ProjecteFinal-Cassandra.ipynb
output
naive_bayes_classifier.pickle
README.md
setup.py
TwitterSentimentAnalysis
manager
models
data_processing.py
__init__.py
regexps.py
TwitterTokenizer.py
En el directorio data, incluiremos todos los ficheros de datos a procesar. En nuestro caso,
se trata de un CSV que contiene twits ya marcados con el sentimiento.
El fichero environment.yml se utiliza para definir las dependencias del entorno virtual
(venv) de Python. En él podremos definir tanto dependencias que incluya Anaconda de
por sí, como indicarle que instale nuevas desde pip.
El directorio figures incluiría gráficos y plots, si generásemos alguno.
En notebooks almacenaremos las libretas de Jupyter correspondientes al proyecto. Las
libretas de Jupyter son ficheros basados en JSON, que combinan tanto celdas de texto
(escritas en Markdown, que luego se renderiza), como de código ejecutable. Éste se eje-
cuta celda por celda, cuando el usuario decide ejecutarlas. El hecho de poder controlar
la ejecución de las celdas, junto a la posibilidad de combinarlas con Markdown, las hace
especialmente ideales para describir código en una presentación o seminario.
En el caso de nuestro proyecto, incluimos dos libretas:
33
9.2 Instalación del proyecto 9 ANEXO: ESTRUCTURA Y INSTALACIÓN DEL PROYECTO
El directorio output contiene ficheros resultantes del procesado. Por ejemplo, el clasificador
ya entrenado en formato Pickle, y un fichero CSV que contiene los resultados del análisis
de sentimiento de twits previamente desconocidos.
El fichero setup.py nos permitirá instalar las dependencias del virtualenv una vez instalado,
mediante la instrucción python setup.py install
Dentro de TwitterSentimentAnalysis tenemos nuestro código fuente, comprendido en los
siguientes ficheros:
• La declaración del módulo en __init__.py. Ésto nos permitirá importar el código en las
libretas de Jupyter.
• texto durante el proceso de preparado de los datos.
• data_processing.py incluye los métodos mediante los que trataremos el texto durante
el proceso de preparado de los datos.
• TwitterTokenizer.py es una clase personalizada mediante la cual separaremos los twits
en Tokens. Incluye expresiones regulares para tratar correctamente elementos co-
munes en twits como las menciones (@usuario), hashtags (#hashtag) y emoticonos.
• Manager y Models contienen el código de GetOldTweets, un proyecto en Github que
utilizamos para extraer los twits.
Creando el entorno
conda env create -f environment.yml
Activando el entorno
# El nombre será el definido dentro del fichero environment.yml
4. Una vez activado el venv, si deseamos instalar nuevos paquetes mediante pip, podemos
hacerlo añadiéndolos al environment.yml y actualizando el entorno de la siguiente manera:
34
9.2 Instalación del proyecto 9 ANEXO: ESTRUCTURA Y INSTALACIÓN DEL PROYECTO
Actualizando el entorno
conda env update environment.yml
6. Cuando tengamos ya el entorno virtual activo, todo lo que ejecutemos en relación a Python,
estará aislado de la instalación nativa del sistema: el intérprete incluso. Ésta es la carac-
terística principal de los entornos virtuales: la posibilidad de definir entornos aislados entre
sí, cada uno con versiones específicas de los paquetes.
Antes de entrar a la libreta, deberemos cerciorarnos de que el entorno virtual que acabamos
de configurar está disponible para su uso en la libreta de Jupyter. Para ello, utilizaremos el pa-
quete iPykernel que hemos especificado en las dependencias:
Con el entorno activo, sólo hará falta ejecutar jupyter notebook para que se abra en el nave-
gador la ventana principal del programa, quedando únicamente navegar al directorio dónde teng-
amos las libretas en cuestión, abrirla, y seleccionar el kernel que acabamos de configurar en el
menú superior, en Kernel >Change Kernel.
35
10 ANEXO: TIPOS DE DATOS EN CQL
36
Glosario REFERENCIAS
Glosario
aprendizaje no supervisado se dice de aquellas tareas de aprendizaje máquina destinadas a
describir estructuras en aquellos datasets sin clasificar..
aprendizaje supervisado se dice de aquellas tareas de aprendizaje máquina en las que un
dataset con observaciones previamente clasificadas está disponible..
hashtag texto precedido por una almohadilla, representando una etiqueta que ayuda a encontrar
mensajes que hablen del mismo tema.
variable categórica se dice de una variable que puede tomar un valor de un juego limitado de
valores.
variable contínua se dice de una variable numérica o de fecha, que tiene infinitos valores entre
dos valores determinados.
variable discreta se dice de una variable numérica que tiene un número contable de valores
entre dos valores determinadods.
Referencias
Codd, Edgar F. (1970). “A Relational Model of Data for Large Shared Data Banks”. En: Commun.
ACM 13.6, págs. 377-387. ISSN: 0001-0782. DOI: 10.1145/362384.362685. URL: http://doi.
acm.org/10.1145/362384.362685.
Hayashi, Chikio (1998). “What is Data Science ? Fundamental Concepts and a Heuristic Exam-
ple”. En: Data Science, Classification, and Related Methods: Proceedings of the Fifth Confer-
ence of the International Federation of Classification Societies (IFCS-96), Kobe, Japan, March
27–30, 1996. Ed. por Chikio Hayashi y col. Tokyo: Springer Japan, págs. 40-51. ISBN: 978-4-
431-65950-1. DOI: 10.1007/978-4-431-65950-1_3. URL: http://dx.doi.org/10.1007/978-
4-431-65950-1_3.
Yanyong, Zhu y Xiong Yun (2011). Datalogy and Data Science: Up to Now. En la web, visitado el
21 de marzo de 2017. URL: www.paper.edu.cn/en_releasepaper/content/4432156.
Wickham, Hadley (2014). “Tidy data”. En: The Journal of Statistical Software 59 (10). URL: http:
//www.jstatsoft.org/v59/i10/.
Carpenter, Jeff y Eben Hewitt (2016). Cassandra: The Definitive Guide. 2.a ed. O’Reilly Media.
ISBN : 3257227892.
Smith, F. Jack (2006). “Data science as an academic discipline”. En: Data Science Journal 5,
págs. 163-164. DOI: 10.2481/dsj.5.163.
Atkinson, Malcolm y col. (1992). “Building an Object-oriented Database System”. En: ed. por
François Bancilhon, Claude Delobel y Paris Kanellakis. San Francisco, CA, USA: Morgan
Kaufmann Publishers Inc. Cap. The Object-oriented Database System Manifesto, págs. 1-20.
ISBN : 1-55860-169-4. URL : http://dl.acm.org/citation.cfm?id=140592.140595.
37