Mostrando entradas con la etiqueta Python. Mostrar todas las entradas
Mostrando entradas con la etiqueta Python. Mostrar todas las entradas

miércoles, 23 de diciembre de 2020

Estadística descriptiva con Python

Debes estar muy aburrid@ en el trabajo, o no tienes nada mejor que hacer, para pinchar en un enlace con la palabra clave 'Estadística'. Pero... ya que has pinchado intentaré que se haga lo más ameno posible.

Esta entrada está pensada para hacer una pequeña visita guiada por la librería de pandas en su sección de estadística. Y es que cuando hablamos de Python y de estadística es inevitable que surja pandas, pues tiene debajo todo el poder de la librería numpy para hacer multitud de cálculos de una forma muy eficiente.

Ya verás qué pronto te encariñas con estos seres.


Lo primero, (y evidentemente lo más importante) es importar dicha librería para poder utilizarla, para aquellas personas que no estéis familiarizadas se hace de la siguiente forma:


A continuación, vamos a 'cargar' algunos datos, para luego poder ver algunas de las estadísticas. ¿Que, qué datos voy a cargar? Pues las estadísticas de todos los Pokémon de la 1º a la 6º generación que son 800 en total (Para aquellas personas que no estén familiarizadas con este mundillo de Pokémon no os preocupéis, os vais a enterar igual).

¡Vamos a la obra!


En primer lugar, decirte que en pandas cuando hablamos de unos datos en formato 2D (con filas y columnas) se le denomina DataFrame (DF para acortar), y es muy habitual utilizar sus siglas para crear una variable que contenga un DataFrame. En este caso llamaré df_pkm al DataFrame con todos los datos de los Pokémon, y para leer esos datos usaremos .read_csv( ) y posteriormente echaremos un vistazo a los datos que tenemos con .head( )


Hagamos un inciso para que entiendas los datos.

Las columnas de Type hacen referencia a la 'familia' a la que pertenece uno de estos entrañables seres, por ejemplo, Pikachu (probablemente el más conocido) es de tipo eléctrico. Las columnas que van desde HP (Health Points) hasta Speed, hacen referencia a los atributos de estos seres, expresado en formato de puntos, en lo que a mayor número mejor es en este aspecto, y la columna Total es la suma de todas estas columnas. La columna Generation hace referencia a cuando salió dicho Pokémon en los juegos (del 1 al 6) y la Legendary hace referencia a si es un Pokémon con unas estadísticas muy especiales. Después de esta mini-chapa (pero fundamental para entender el contexto) sigamos con lo que cierne al título de esta entrada.

Este es Pikachu, seguro que te suena


Una vez tenemos cargado nuestro .csv en un DF, y antes de pasar a la parte de estadística, es fundamental comprobar el estado de nuestros datos, ya que, si no tenemos nuestros datos en un formato numérico (int, float, complex) no podremos operar con ellos como si fuesen números (Y sí, a veces ocurre que una columna que parece que está en formato numérico, pero en realidad está en un formato de texto (object)) . Para hacer una inspección rápida utilizaremos .dtypes 


Aquí podemos comprobar que todas nuestras columnas que tienen números están en un formato numérico, por lo tanto, ¡podemos continuar!

Ahora vamos a sacar estadísticas de todos estos datos. Para ello usaremos una de las herramientas que con una simple instrucción podemos sacar las estadísticas más importantes, y esa no es otra que .describe( )



Nada mal para una sola línea de código tan simple ¿eh?, este es el poder que reside en pandas. De esta forma de un simple vistazo tenemos muchas estadísticas a la vista, como puede ser la media, la desviación estándar, el mínimo o el máximo y los percentiles. Hay que decir, que la columna de Generation no tiene sentido en esta tabla, pues son valores discretos que van del 1 al 6 en función de cuando salió dicho Pokémon. Y como te puedes fijar solo ha hecho el análisis de aquellas columnas numéricas, el resto las ha obviado, por ello es fundamental comprobar primero el tipo de dato que tenemos.

Si quieres acceder a un dato en concreto solo tienes que seguir la siguiente sintaxis:

¿Y si en lugar de números lo vemos en un gráfico?

Otra ventaja que presenta pandas es que además de tener numpy debajo para hacer los cálculos numéricos, tiene también a matplotlib, una librería diseñada para representar gráficos. La conjunción de estas dos librerías más lo que aporta pandas hace que sea una de las herramientas más utilizadas en Python.

Volviendo a nuestros datos, probablemente la mejor forma de representar este tipos de datos sea mediante un diagrama de cajas y bigotes, para ello usamos .boxplot( ). Y seleccionaré aquellas columnas que realmente tienen interés, dejando de lado a 'Total' que es la suma de las que represento en el siguiente diagrama y a 'Generation':


Como puedes observar con comandos sencillos se pueden obtener buenos resultados.


¿Qué tal si ahora para finalizar ponemos fin a la lucha que ha habido siempre en el mundillo de Pokémon usando la estadística?

Por fin sabremos si es mejor el tipo agua, fuego o planta (Para aquellas personas que no estén al día, al principio de todos los juegos te hacen elegir un Pokémon de entre estos 3 tipos, pero en el juego en general hay muchos más tipos). Lo que haremos será hacer este mismo gráfico pero para cada uno de esos tipos (agua, fuego y planta) y compararemos las gráficas para salir de dudas de cuál es el mejor tipo.

En primer lugar, lo que haremos será filtrar nuestro DF dejando únicamente aquellos Pokémon de tipo agua, fuego o planta, y guardaremos ese nuevo DF en pkm_wfg (wfg de las siglas de water, fire y grass), para ello haremos uso .loc[ ] y de .isin( )

Y finalmente, usaremos de nuevo .boxplot( ) esta vez con unos parámetros adicionales, el más importante es el 'by' utilizado para agrupar, hay que tener en cuenta que hay que agregar la columna que queremos usar como agregación, por ese motivo, añadiremos 'Type 1' a las columnas que usaremos en nuestro diagrama de cajas y bigotes.

Queda claro que gana el tipo fuego, pero cuidadito con los outliers de tipo agua que pueden apagar muchos incendios, y el tipo planta se queda como robusto siempre entre los dos tipos. Conclusión, no hay conclusión, aún seguiremos debatiendo si elegir entre Squirtle, Charmander o Bulbasaur

Y bueno espero que con esta pequeña visita guiada a pandas te hayas hecho una idea de lo potente que es esta herramienta y que hay muchas aplicaciones a nivel estadístico. Espero que hayas llegado al final y que no te haya matado de aburrimiento.

¡Muchas gracias por leerme!

Todas las imágenes que no son capturas de pantalla han sido sacas de pixabay.com











miércoles, 29 de julio de 2020

Spark: la oportunidad


¡Vivimos una explosión de datos! Cada vez más se requieren más personas que sepan analizar y modelar estos datos para obtener la información. El dato es útil. El dato de alta calidad, bien entendido y auditable, no tiene precio. En este artículo vamos a dar una pincelada sobre este entorno de trabajo, un diamante en bruto, llamado Spark.




Obtenemos datos de todos los medios, como Twitter feeds, Facebook, mensajes, SMS, y una gran variedad de medios.  La necesidad de poder procesar esos datos tan rápidamente como sea posible se convierte en más importante que nunca. 

Hace unos pocos años, la programación mediante MapReduce ha sido útil para estos fines, pero la cantidad de tiempo que se tarda en ejecutar los trabajos no es la más aceptable en la mayoría de las situaciones. La curva de aprendizaje para escribir un trabajo MapReduce también es difícil, ya que requiere conocimientos específicos de programación y el know-how. Además en MapReduce los trabajos sólo funcionan para un conjunto específico de casos de uso. Necesitamos algo que funcione para un gran conjunto de casos de uso.


Apache Spark fue diseñado como una plataforma de computación rápida, de uso general y fácil de usar, de ahí viene su nombre: chispa.

Extiende el modelo MapReduce y lo lleva a otro nivel. La velocidad proviene de los cálculos en memoria. 

Las aplicaciones que se ejecutan en un proceso y con una respuesta mucho más rápida. Spark es incluso más rápido que MapReduce para aplicaciones muy complejas usando los discos. Puede ejecutar la aplicación por lotes, o algoritmos iterativos que se basan unos sobre otros. 

Se pueden ejecutar consultas interactivas y procesar datos de flujos continuos con una aplicación. 
Soporta un número de bibliotecas que pueden utilizarse fácilmente, para expandirse más allá de las capacidades básicas de Spark, son:


La gran facilidad de uso de Spark nos permite aprender rápidamente usando los APIs simples para Scala, Python, R y Java. Spark se ejecuta en clústeres Hadoop con YARN  o Apache Mesos, o incluso de manera autónoma con su propio planificador


¿Por qué y para qué querríamos usar Spark?


Spark proporciona procesamiento distribuido paralelo, tolerancia a fallos en hardware de productos básicos, escalabilidad, etc...Añade el concepto de computación agresiva en caché de memoria distribuida, con baja latencia, APIs de alto nivel y pila de herramientas de alto nivel. 

Hay dos grupos que podemos considerar aquí que querrían usar Spark: Científicos de Datos e Ingenieros (Analistas de Datos).

 ¿Pero no son similares?

En cierto sentido, sí, tienen superposición de conjuntos de habilidades, pero para nuestro propósito, vamos a definir al científico de datos como aquellos que necesitan analizar y modelar los datos para obtener información. Tendrían técnicas para transformar los datos en algo que pueden utilizar para el análisis de datos. 
  • Su análisis ad-hoc.
  • Ejecutar consultas interactivas que les proporcionen resultados inmediatamente. 
Los Científicos de datos también tienen experiencia en el uso de SQL, estadísticas, aprendizaje automático y algo de programación, por lo general usando lenguajes como Python o R.

Una vez que los científicos de datos han obtenido la información sobre los datos; más tarde, alguien determina que hay una necesidad de desarrollar una aplicación de procesamiento de datos de producción, una aplicación web, o algún sistema, la persona llamada a trabajar en ello estarían los ingenieros (analistas de Datos).

Los ingenieros (analistas de datos) utilizarían la API de programación de Spark para desarrollar un sistema de casos de uso. Spark paraleliza estas aplicaciones a través de los clústeres mientras se ocultan las complejidades de la programación de los sistemas distribuidos y tolerancia a fallos.  Pueden usar Spark para monitorear, inspeccionar y ajustar las aplicaciones. 

Spark Core, componentes...


El núcleo de Spark (Core) está en el centro de todo. Es un sistema de propósito general que proporciona programación, distribución y supervisión de las aplicaciones a través de un grupo de componentes.

Los componentes en la parte superior del Spark Core que están diseñados para trabajar internamente, dejando que los usuarios los combinen, como lo harían con cualquier biblioteca en un software de proyecto. El beneficio de esta pila es que todos los componentes de la capa superior heredarán las mejoras realizadas en las capas inferiores. 

El Spark Core está diseñado para escalar de uno a miles de nodos. Proporciona la abstracción fundamental de Spark: Resilient Distributed DataSet (RDD):
  • Resilient (Flexible): si se pierden los datos en la memoria, se pueden volver a crear
  • Distribuido: procesado en todo el clúster 
  • DataSet (conjunto de datos): los datos iniciales pueden provenir de una fuente, como un archivo, o pueden ser creados mediante programación

Los RDD son anteriores a Spark SQL y al API de los DataFrame / Dataset.

Spark SQL está diseñado para trabajar con Spark a través de SQL y HiveQL e Impala. Spark SQL permite a los desarrolladores mezclar las consultas de SQL con el lenguaje de programación de Spark elegido: Python, Scala, R o Java. 

Funciona con datos estructurados


DataFrames y Datasets que son la abstracción de los datos estructurados. Posee además un entorno de optimización de las consultas: el Catalyst Optimizer

Spark Streaming proporciona acceso al proceso de flujos de datos en tiempo real. Su API coincide con el de Spark Core, lo que facilita a los desarrolladores moverse entre aplicaciones que procesan los datos almacenados en la memoria y/o llegar a ejecutarlos en tiempo real, proporcionando el mismo grado de tolerancia a fallos, rendimiento y escalabilidad que ofrece el Spark Core.

MLlib, la biblioteca de aprendizaje automático de máquina (Machine Learning), proporciona múltiples tipos de algoritmos que están diseñados para escalar a través del clúster.

GraphX es una biblioteca de procesamiento de gráficos (Graph Processing) con API para manipular gráficos y realizar gráficos computacionales en paralelo.

Los DataFrames y los DataSets son la representación principal de los datos en Spark.
  • Los DataFrames representan datos estructurados en forma de tabla. Son similares a las tablas en un RDBMS. Consisten en una colección de objetos Row (fila) sin escribir. Las filas se organizan en columnas descritas por un esquema. 
  • Los DataSets representan datos como una colección de objetos de un tipo específico. Están fuertemente tipados
  • Realmente un DataFrame es un alias de un Dataset [Row]: conjuntos de datos que contienen objetos Row (filas)
Cómo veis, el entorno de Spark no es difícil ni complicado, simplemente requiere perseverancia para familiarizarse con él y una vez conseguido estaréis en disposición de entrar en un mundo apasionante, desafiante y novedoso tecnológico. Espero que pongáis más de una chispa en vuestro camino.





¡Hasta el próximo post queridos lectores!