Split-Apply-Combine-Parte 2

Parte 2.-Procesando los datos y analizando otras posibles relaciones.

En la primera parte solo puse algunos ejemplos de gráficas que se pueden generar de manera directa de los datos sin hacer ningún procesamientos sobre la información.

Existen varias librerías para procesar datos en R project, las que aparecen en mayor cantidad de referencias son reshape2, dplyr y data.table. Para realizar un procesa SAC en los datos, no basta con solo revisar las variables de manera directa, es recomendable hacer un poco de procesamiento de los datos para realizar una exploración más sutil sobre la información.

En la entrada “Algo de procesamiento de datos” compartí algunos ejemplos sencillos del uso de las tres librerías de R y sobre el procesamiento de datos en Python con Pandas. Por lo cual no explico todos los detalles sobre las funciones, para más detalles se puede revisar esa entrada o las referencias que dejé en esa entrada.

Algo más

Usando dplyr y reshape2, se pueden explorar otro tipo de relaciones entre los datos. Ejemplo, la información de los vuelos cuenta con 16 variables de las cuales 3 de ellas indican el año, mes y día. Estas tres variables pueden permitir construir la variable de fecha la cual nos permite preguntarnos sobre la información desde un punto de vista de series de tiempo.

Una serie de tiempo es analizar el comportamiento de un indicador con respecto a la variación del tiempo, esto si bien no es claro lo muestro en el ejemplo. Formalmente es un proceso estocástico que tienen un parámetro t de tiempo.

La intención con ciertas transformaciones y agrupamientos de los datos es permitir explorar la información de manera diferente a lo que podemos hacer directamente desde la tabla de datos.

Tratamiento 1

#Se cargan los datos y las librerías requeridas para el análisis
#Se cargan las librerías
library(nycflights13)
library(dplyr)
library(reshape2)
library(ggplot2)

#Revisión de los datos
data("flights")
dim(flights)
#[1] 336776 16
#missing value
#Se eliminan las filas sin datos completos

sum(is.na(flights))
#[1] 60593
flights2=na.omit(flights)
head(flights2,10)
str(flights2)
dim(flights2)
#[1] 327346 16

#Agrupamos por fechas y aeropuerto de origen
a1<-flights2%>%
 group_by(year,month,day,origin)%>%
 summarise(count=n(),retrasos=sum(dep_delay+arr_delay),distancia=mean(distance))

#Se revisan el tipo de datos con los siguientes comenados
head(a1)
dim(a1)
#[1] 1095 7
str(a1)

#Agrego una variable para la fecha

a2=mutate(a1,fechas=as.Date(paste(month,day,year,sep="/"),"%m/%d/%Y"))
dim(a2)
#1095 8
str(a2)

head(a2)
#Source: local data frame [6 x 8]
#Groups: year, month, day

 #year month day origin count retrasos distancia fechas
#1 2013 1 1 EWR 300 11455 1039.8033 2013-01-01
#2 2013 1 1 JFK 295 5944 1297.1424 2013-01-01
#3 2013 1 1 LGA 236 2617 843.6695 2013-01-01
#4 2013 1 2 EWR 341 17242 1010.3900 2013-01-02
#5 2013 1 2 JFK 317 3641 1281.3502 2013-01-02
#6 2013 1 2 LGA 270 3589 841.9519 2013-01-02

Lo que se hizo con el código anterior fue construir desde los datos originales un data.frame o una tabla de datos con la información ordenada de otro modo y lista para poder explorarla como serie de tiempo. Lo que se hizo fue contabilizar la cantidad de vuelos por día, sumar los minutos de retraso al despegar y al arribar y calcular la distancia media recorrida por día.

Se pueden hacer algunas cosas con esta información, primero visualizar el comportamiento de los datos por cada aeropuerto de origen y después explorar si existe alguna relación entre las 3 series de tiempo.

 #Serie de tiempo 1
ggplot(a2,aes(x=fechas,y=count))+geom_line(aes(colour=factor(origin)))+scale_x_date()+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Número de vuelos por año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Cantidad de vuelo")+xlab("Fecha de Vuelos")

La gráfica es la siguiente:

Serie_T1

#Serie de tiempo 2
ggplot(a2,aes(x=fechas,y=retrasos))+geom_line(aes(colour=factor(origin)))+scale_x_date()+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Minutos de retrasos por vuelo en el año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Minutos de retraso")+xlab("Fecha de Vuelos")

La gráfica es la siguiente:

Serie_T2

#Serie de tiempo 3
ggplot(a2,aes(x=fechas,y=distancia))+geom_line(aes(colour=factor(origin)))+scale_x_date()+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Media de la distancia de vuelo por año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Media de la distancia de vuelo")+xlab("Fecha de Vuelos")

La gráfica es la siguiente:

Serie_T3

Revisando el “cruce” entre la cantidad de vuelos, la distancia media y el total de minutos de retraso se obtienen las siguientes gráficas.

#Cruce 1
ggplot(a2,aes(count,retrasos))+geom_point(aes(colour=origin))+facet_grid(.~origin)+geom_smooth(col="black")
 ggtitle("Scatter plot de Cantidad de vuelos vs retrasos ")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Cantidad de Vuelos")+xlab("Retrasos por Aeropuertos")

La gráfica que se obtiene es la siguiente:

SC1

#Cruce 2
ggplot(a2,aes(count, distancia))+geom_point(aes(colour=origin))+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Scatter plot de cantidad de vuelos vs distancia media por año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Cantidad de Vuelos")+xlab("Distancia media por Aeropuertos")

La gráfica es la siguiente:

SP2

#Cruce 3
ggplot(a2,aes(y=distancia,x=retrasos))+geom_point(aes(colour=origin))+facet_grid(.~origin)+geom_smooth(col="black")+
 ggtitle("Scatter plot entre la distancia media y los retrasos por año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Media de la distancia de vuelo")+xlab("Retrasos por Aeropuertos")

La gráfica es la siguiente:

SC3

El único fin de las 6 gráficas anteriores es tratar de detectar alguna información o relación entre la información que con los datos originales no sea visible.

Analizando someramente las gráficas se puede observar en la primera gráfica que en los dos primeros aeropuertos el comportamiento es “similar”, ya que incremente la cantidad de vuelos de primavera hasta verano y posteriormente decrece cuando el año llega al invierno.La diferencia con el aeropuerto LGA que muestra un incremento conforme el año se acerca al invierno.

En la segunda gráfica se aprecia que para los 3 aeropuerto los retrasos incrementan en verano, con un poco de cuidado se aprecia que entre los meses de Febrero e inicio de Marzo se muestra un pico en los retrasos, el cual puede deberse a la temporada de cierre de nevadas.

El tercero resulta claro cual aeropuerto es requerido para vuelos con distancias mayores, JFK, y cual parece para vuelos cercanos. Revisando esto con la gráfica 1 se puede tener sospechas de que el incremento en la cantidad de vuelos en el aeropuerto LGA al cierre de año está relacionado con que se realizan vuelos cortos, lo cual puede estar relacionado con los festejos de cierre de año y periodos vacacionales.

Las últimas 3 gráficas son más sutiles, ya que se requeriría revisar la correlación y el coeficiente de información mutua para explorar si existe alguna relación interesante en los cruces. Por ejemplo la gráfica 5 muestra ciertas relaciones lineales negativa entre la cantidad de vuelos y la media de distancia en el aeropuerto LGA, pero en los otros dos no se muestra que exista dicha relación.

La gráfica 4 y 6 no muestran relaciones lineales, pero es posible que si tengan relaciones no lineales para lo cual se podría usar el índice de información mutual para tener algún indicio.

 Lo que debe de estar claro es que con unas agrupaciones y transformaciones se pudo explorar la información desde otra perspectiva y permite pensar en hacer cierto tipo de análisis, ejemplo las tres primeras gráficas permiten incitar en realizar un análisis de series de tiempo de los datos y con ellos crear un modelo predictivo de la cantidad de vuelos por mes o el comportamiento de los retrasos por mes.

Tratamiento 2

El siguiente ejemplo son dos partes, la primera es elegir el número de cola del avión con mayor cantidad de vuelos realizados y analizar sus comportamiento con respecto al año. Por último tomo un ejemplo que resulta similar al presentado en la página de referencia de la librería dplyr, con algunas ligeras variaciones.

Para elegir la cola de avión con mayor cantidad de vuelos, es decir; la variable tailnum agrupo la información con respecto a esa variable y resumo la información para conocer el registro con mayor número de vuelos.

#Agrupación
plane1<-flights2%>%
   group_by(tailnum,origin)%>%
   summarise(count=n(),retrasos=sum(arr_delay),med_distancia=mean(distance))

head(plane1)
#Source: local data frame [6 x 5]
#Groups: tailnum

 #tailnum origin count retrasos med_distancia
#1 D942DN JFK 1 2 944.0000
#2 D942DN LGA 3 124 824.6667
#3 N0EGMQ EWR 48 531 719.0000
#4 N0EGMQ JFK 27 361 517.6667
#5 N0EGMQ LGA 277 2622 688.2816
#6 N10156 EWR 144 1706 758.6458

max(plane1$count)
#536
filter(plane1,count==536)
#Source: local data frame [1 x 5]
#Groups: tailnum

#tailnum origin count retrasos med_distancia
#1 N725MQ LGA 536 2508 561.4515

De este modo tenemos que N725MQ es el registro que tienen mayor cantidad de vuelos. Entonces filtro la información original para analizar solo los datos correspondientes a este registro.

#Filtro
Plane_N725MQ=filter(flights2,tailnum=="N725MQ")
#Observo en breve la información
head(Plane_N725MQ)
#Source: local data frame [6 x 16]

#year month day dep_time dep_delay arr_time arr_delay carrier tailnum
#1 2013 1 1 832 -8 1006 -24 MQ N725MQ
#2 2013 1 1 1305 -10 1523 3 MQ N725MQ
#3 2013 1 1 1840 -5 2055 25 MQ N725MQ
#4 2013 1 2 1205 0 1349 4 MQ N725MQ
#5 2013 1 2 1805 -5 1946 1 MQ N725MQ
#6 2013 1 3 1131 -4 1314 -16 MQ N725MQ
#Variables not shown: flight (int), origin (chr), dest (chr), air_time (dbl),
# distance (dbl), hour (dbl), minute (dbl)

#Agrego dos variables nuevas
Plane_N725MQ1=mutate(Plane_N725MQ,velocidad=distance/air_time*60,fechas=as.Date(paste(month,day,year,sep="/"),"%m/%d/%Y"))

Con lo anterior puedo seleccionar las columnas que deseo analizar y por medio de la librería Reshape2 puedo cambiar su estructura para apreciar su comportamiento con respecto al tiempo, es decir; como serie de tiempo.

#Explorando el comportamiento de su velocidad media y la media de retrasos al arribar

#Se procesan los datos para construir otra estructura de datos 

B1<-Plane_N725MQ1%>%
 group_by(fechas,origin, dest)%>%
 summarise(count=n(),retrasos=mean(arr_delay),vel_media=mean(velocidad))

head(B1)
Source: local data frame [6 x 6]
Groups: fechas, origin

 fechas origin dest count retrasos vel_media
1 2013-01-01 LGA CRW 1 25 277.5000
2 2013-01-01 LGA DTW 1 3 295.2941
3 2013-01-01 LGA RDU 1 -24 335.8442
4 2013-01-02 LGA BNA 1 1 342.0896
5 2013-01-02 LGA RDU 1 4 300.6977
6 2013-01-03 LGA CLE 1 -16 318.2278

#Gráficas para explorar el comportamiento en el año

ggplot(B1,aes(x=fechas,y=vel_media,colour=dest))+geom_line()+scale_x_date()+geom_smooth(col="black")+
 ggtitle("Comportamiento de la velocidad en el año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Velocidad media de vuelo")+xlab("Fecha de Vuelos")

ggplot(B1,aes(x=fechas,y=retrasos,colour=dest))+geom_line()+scale_x_date()+geom_smooth(col="black")+
 ggtitle("Comportamiento de los retrasos en el año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Media de los retraos en los vuelos")+xlab("Fecha de Vuelos")

Las gráficas que se obtienen son las siguientes:

N725MQ

N725MQ_retrasos

En las dos gráficas se aprecian comportamiento peculiares para ciertos destinos de vuelo, cada sigue un comportamiento. En la primera gráficas resalta el comportamiento de BNA y CLE, el primero está sobre la línea de tendencia y el segundo tiene bajas de media de velocidad considerables para el periodo de Abril a Julio.

En la segunda gráfica se aprecia un comportamiento de mayor media en los retrasos entre los meses de Abril-Mayo y en otro momento en los meses de Junio-Julio.

En resumen, esta exploración permite centralizar el análisis en los destinos que resultan con comportamiento más extraños, con esta sospecha se puede procesar la información para analizar como se comportan el resto de vuelos con respecto a esos destinos.

Otro modo de procesar los datos  y realizar el análisis es revisar como se comportan los retrasos pero dividida por aeropuerto de origen de vuelo, esto se puede hacer fácil haciendo uso de la función melt de la librería Reshape2.

#Separación del análisis

#Se procesan lo datos originales
B2<-Plane_N725MQ1%>%
 group_by(fechas,origin, dest)%>%
 summarise(retrasos_arr=mean(arr_delay),retrasos_dep=mean(dep_delay))

#Construyo una table que permita el análisis de los datos de manera sencilla

datos=melt(B2,id=c("fechas","origin","dest"))

#Con el comando head() se visualiza como se ordena la información
head(datos)
#     fechas origin dest variable value
#1 2013-01-01 LGA CRW retrasos_arr 25
#2 2013-01-01 LGA DTW retrasos_arr 3
#3 2013-01-01 LGA RDU retrasos_arr -24
#4 2013-01-02 LGA BNA retrasos_arr 1
#5 2013-01-02 LGA RDU retrasos_arr 4
#6 2013-01-03 LGA CLE retrasos_arr -16

#Se analizan los datos gráficamente

ggplot(data=datos,aes(x=fechas,y=value,colour=dest,group=variable))+geom_line()+scale_x_date()+
 ggtitle("Comportamiento de los retrasos en el año")+theme(plot.title=element_text(lineheight = 1,face='bold'))+ylab("Media de los retraos en los vuelos")+xlab("Fecha de Vuelos")+
 facet_grid(.~origin)

La gráfica es la siguiente:

Retrasos_origen-destino

En este último ejemplo queda claro cual es el aeropuerto que se usa para despegar y el comportamiento de las medias de retrasos muestra ciertos picos, una ligera alza en los meses de Junio-Julio-Agosto. Este último gráfico se puede obtener desde la primera estructura de datos analizada, la única finalidad de hacer este último ejemplo era mostrar como melt() modifica la información no regresa algo parecido a una tabla pivot de Excel.

La última es prácticamente equivalente a la que se puede consultar en la página de referencia de dplyr, lo único que agregué fue mostrar la referencia de origen de vuelo.

#Última clasificación
#Se agrupan por 2 columnas
by_tailnum <- group_by(flights, tailnum,origin)
head(by_tailnum)
#Se construye el resumen de los datos
 
delay <- summarise(by_tailnum,
 count = n(),
 dist = mean(distance, na.rm = TRUE),
 delay = mean(arr_delay, na.rm = TRUE))

delay <- filter(delay, count > 20, dist < 2000)

#Se genera la gráfica para ver el cruce

ggplot(delay, aes(dist, delay)) +
 geom_point(aes(size = count,colour=origin), alpha = 1/2) +
 geom_smooth() +
 scale_size_area()+
 xlab('Media de la Distancia')+
 ylab('Media de los Retrasos')+
 ggtitle('Cruce de la media de las distancia vs media de los retrasos')+
 theme(plot.title=element_text(lineheight = 1,face='bold'))

La gráfica que se obtiene es la siguiente:

Cruce_dist_vs_retrasos

El patrón que se muestra posiblemente pueda ser estudiado con alguna técnica de clasificación la cual indicaría un aproximado de como se aglomera la información, pensando burdamente en usar cluster supongo que jugando con 5 cluster podría obtenerse un modelo simple sobre los datos.

En Python

PENDIENTE

Anuncios

Split-Apply-Combine-Parte 1

Sobre Split-Apply-Combine

La idea de esta entrada es aplicar la visión de dividir-aplicar-combinar (Split-Apply-Combine), en las referencias [1,2] se explican más detalles sobre el modelo o metodología guía, la cual fue inspirada por Map-Reduce. Esta última es una metodología apropiada cuando se tienen un cluster de computadoras, en este caso la versión Split-Apply-Combina se centra en el caso del análisis de datos mediante una sola máquina para diseñar una buena estrategia de análisis.

En la entrada desarrollo el ejemplo mediante R project y Python. La intención es mostrar como los dos lenguajes cuentan con las herramientas para realizar el mismo tipo de análisis. Trato de hacer un ejemplo amplio, por lo cual elegí una base más o menos grande de R project, la cual si bien no tiene muchas variables ( solo 16) permite hacer varias cosas con ellas. Por supuesto que el análisis puede tener otro tipo de enfoque, lo único que hago es usar esa base para emplear varias herramientas de R y de Python, las cuales en general uno las consulta de mera independiente.

Divido esta entrada en 3 partes.

Parte 1.-Exploración directa de los datos.

Parte 2.-Procesando los datos y analizando otras posibles relaciones.

Parte 3.-Definiendo técnicas para aplicar y concentrar esto para realizar un proceso Split-Apply-Combine.

Decidí dividir en tres partes para compartir algunos ejemplos sencillos sobre como hacer algunos gráficos y también un poco de análisis. Todos los gráficos usados entran perfectamente en los temas de exploración de datos o análisis exploratorio, en ocasiones solo uso algunas funciones para mostrar como funcionan y el valor que agrega a la exploración puede ser pobre y sin relevancia mayor.

En la referencia [3] se pueden ver detalles sobre las gráficas en R y en la referencia [4] sobre las gráficas en Python.

Parte 1.-Exploración directa de los datos.

En el código considero instaladas las librerías requeridas, en caso de contar con ellas  en caso de usar RStudio se puede hacer uso de Tools para instalar paquetes, lo cual es rápido y fácil.

Los datos corresponden a los tiempos de vuelo del año 2013, contienen información de los vuelos de 3 aeropuertos JFK, LGA y EWR.

#Código para cargar las librerías y datos
library(nycflights13)
library(ggplot2)
library(grid)
library(GGally)
library(gridExtra)#Funciones para la librería Grid

Los datos en general primero son explorados para conocer cuantos datos se tienen como missing values y las dimensiones de estos datos, es decir; cuantas columnas y cuantas filas tiene el archivo.

#Código para revisar las propiedades básicas de los datos
data(flights)
#Para conocer información de los datos 
#?flights

dim(flights)
#[1] 336776     16

#missing value
sum(is.na(flights))
#[1] 60593
flights2=na.omit(flights)
dim(flights2)
#[1] 327346     16

#tipo de datos
str(flights2)
#Aspectos básicos de los datos
head(flights2)
#También se puede ver la parte final de la tabla de datos
#tail(flights2)

#Para revisar el resumen estadístico de los datos
#Se usa el siguiente comando

summary(flights2)

Debido a que se tienen varias variables que son categóricas, se puede revisar su comportamiento considerándolas como “factores”. Un modo de revisar como se comportan ese tipo de datos se puede hacer con el siguiente comando.

#Explorando unas variables categóricas

sort(summary(factor(flights2$dest)),decreasing = TRUE)
sort(summary(factor(flights2$origin)),decreasing = TRUE)
#EWR    JFK     LGA
#117127 109079  101140

Cuando se revisan los datos de manera numérica uno no aprecia mucho la relevancia del comportamiento de los datos. Entonces siempre se buscan algunas gráficas sencillas que representen la información de manera clara y fácil.

Todas las gráficas siguientes pueden ser mejoradas, al final depende del interés de cada persona para definir el tipo de gráfica que se hace.

#Primeras Gráficas

p1=ggplot(data=flights2,aes(x=factor(origin),y=month))+geom_boxplot(col="black",alpha=0.7,aes(fill=factor(origin)))+
xlab('Origen de los Vuelos')+ylab('Mes de vuelo')+ggtitle('Comportamiento de los lugares de salida por mes')+theme(plot.title=element_text(lineheight = 2,face='bold'))

p2=ggplot(data=flights2,aes(x=factor(month)))+geom_bar(col="black",aes(fill=factor(origin)),position="dodge")+
  xlab('Mes de Vuelos')+ylab('Número de vuelos')+ggtitle('Comportamiento de vuelos por mes con respecto al aeropuerto de salida')+theme(plot.title=element_text(lineheight = 2,face='bold'))

grid.arrange(p1,p2,ncol=2,main="Gráficas del comportamiento de vuelos por mes")

La gráfica que se obtiene es la siguiente:Gráficas_vuelos_por_mesLa intensión es revisar la relación que existe entre la cantidad de vuelos por mes respecto al aeropuerto de salida u origen. La primera gráfica muestra como los 3 aeropuertos tienen un mes en el cual es la media de vuelos y por otro lado el JFK muestra que cubre un mayor número de meses con actividad. En las barras se observa que en EWR se realiza un mayor número de vuelos, además muestra las altas en vuelos en primavera y verano.

##Comportamiento de los tiempos de retraso de despegue y de arrive

q1=ggplot(data=flights2,aes(x=dep_time))+geom_histogram(color="black",aes(fill=factor(origin)))+
  xlab('Hora de despegue')+ylab('Número de Vuelos')+ggtitle('Hora de Despegue por aeropuerto de salida')+theme(plot.title=element_text(lineheight = 2,face='bold'))

q2=ggplot(data=flights2,aes(x=arr_time))+geom_histogram(colour="black",aes(fill=factor(origin)))+
  xlab('Hora de arrivo')+ylab('Número de vuelos')+ggtitle('Hora de Arrivo por aeropuerto de salida')+theme(plot.title=element_text(lineheight = 2,face='bold'))

grid.arrange(q1,q2,nrow=1,ncol=2,main="Gráficas del comportamiento de vuelos por mes")

El gráfico que se obtiene es:

Despegue_y_arrivo_por_aeropuertoSe muestran los histogramas de la cantidad de vuelos por hora de despegue y arribo divididos por el aeropuerto de origen. Se aprecian las horas en las cuales se realizan el mayor número de vuelos , los cuales son sumamente notorios. Por otro lado se aprecia la hora de llegada, las cuales muestran cuatro horas pico o el horario con mayor número de arribos.

En la base de datos se tienen registrados los minutos de retraso en despegues y en arribos a su destino, una idea sencilla es graficar el cruce de ambos datos y explorarlos.

#Gráfica de retrasos en despeque y arrivo
ggplot(data=flights2,aes(x=dep_delay,y=arr_delay))+geom_point(aes(colour=factor(origin)))+
  geom_smooth(method='lm',colour='black')+
  xlab('Retraso en Despegar')+ylab('Retraso en arrivo')+ggtitle('Relación entre retraso de despegue y arrivo por aeropuerto')+theme(plot.title=element_text(lineheight = 2,face='bold'))

La gráfica que se genera es la siguiente:

Relación_despegue_vs_arrivoAgregué la línea de tendencias entre los datos calculada con la regresión lineal entre los datos. Esta recta muestra una buena descripción gráficamente o eso aparenta, pero con un poco de cuidado se ve que los mejores datos descritos son aquellos que tienen mayor tiempo de retraso, mientras que la mayoría de datos se muestran como una mancha en los primeros 500 minutos.

Lo que se me ocurrió revisar el comportamiento de la distribución de los datos, haciendo uso de un histograma, después de observar que solo se apreciaba unas cuantas barras estimadas probé transformar los dato y calcular su logaritmo y luego volver a revisar su histograma. Lo que se observa de los datos transformados es la siguiente gráfica:

Hist_Dist_despegue_y_arrivosLa cual se puede obtener con el siguiente código:

#Tranformación de los datos e Histograma
l1=ggplot(data=flights2,aes(x=log(87+arr_delay)))+geom_histogram(color="black",aes(fill=factor(origin)))+
xlab('Log(87+arr_delay)')+ylab('Conteo')+ggtitle('Histograma de los retrasos en tiempo de arrivo')+theme(plot.title=element_text(lineheight = 2,face='bold'))

l2=ggplot(data=flights2,aes(x=log(43+dep_delay)))+geom_histogram(color="black",aes(fill=factor(origin)))+
  xlab('Log(43+dep_delay)')+ylab('Conteo')+ggtitle('Histograma de los retrasos de tiempo de despegues')+theme(plot.title=element_text(lineheight = 2,face='bold'))

grid.arrange(l1,l2,nrow=1,ncol=2,main="Gráficas del comportamiento de vuelos por mes")

Se observa entonces que los datos muestran comportamientos de distribuciones de cols pesadas, lo cual requiere una revisión más meticulosa. Haciendo el gráfico de cruce entre los dos tiempos de retrasos, pero considerando sus valores transformados se obtienen el siguiente gráfico log-log.

Log_vs_log_distancia-arrivosEl otro par de variables que sugiere que tienen alguna relación son la distancia del vuelo y el tiempo de vuelo. La gráfica se puede realizar con el siguiente código:

ggplot(data=flights2,aes(x=air_time,y=distance))+geom_point(aes(colour=factor(origin)))+
  xlab('Tiempo de vuelo')+ylab('Distancia recorrida')+ggtitle('Cruce entre la distancia y el tiempo de vuelo')+theme(plot.title=element_text(lineheight = 2,face='bold'))

La gráfica que se obtiene es la siguiente:

Cruce_Dis_vs_Tiempo_vueloLa gráfica a primera vista sugiere una relación lineal, pero también se puede explorar si no resulta favorable considerar el log-log de los datos, esto por aquellos datos que muestran desconexión en la parte superior de la gráfica.

ggplot(data=flights2,aes(x=log(distance),y=log(air_time)))+geom_point(aes(colour=factor(origin)))+
  xlab('Logaritmo del Tiempo de vuelo')+ylab('Logaritmo de la Distancia recorrida')+ggtitle('Cruce entre la distancia y el tiempo de vuelo')+theme(plot.title=element_text(lineheight = 2,face='bold'))

La gráfica que se obtiene es la siguiente:

Cruce_Log_de_Dist_vs_Timepo_VueloTambién muestra una relación lineal pero es posible que revisando un ajuste lineal entre los datos sea favorable considerar el log-log para cubrir una mayor  población de los datos.

Los siguientes gráficos solo son ejemplos para explorar la información en busca de alguna posible relación entre los datos.

JitterHoras_de_despegueEl código de los dos gráficos es el siguiente:

ggplot(data=flights2,aes(x=factor(carrier),y=factor(origin)))+geom_jitter()
#ggplot(data=flights2,aes(x=hour))+geom_bar(aes(colour=origin,fill=origin),position = "dodge")+coord_flip()

ggplot(data=flights2,aes(x=hour))+geom_bar(color="black",aes(fill=origin))+
  xlab('hora del día')+ylab('Conteo')+ggtitle('Histograma de las horas de despegue o salida')

Estos dos gráficos, sobre todo el primero; son informativos por ejemplo las barras negras muestran por aeropuerto qué aerolíneas tienen actividad. Es inmediatamente es claro cuales aerolíneas tienen presencia y la diferencia entre la actividad por aeropuerto.

La segunda gráfica muestra 3 momentos donde no se registran vuelos, lo cual resulta raro pero los datos de muestran esto, lo cual implica a ser explorado con mayor detalle.

Un gráfico que suele hacerse entre varias variables o entre una matriz de datos es el scatter plot, para explorar la posible relación entre cada par de variables. Para realizarlo en R con ggplot, se ejecuta el siguiente código:

#Scatter Plot
ggpairs(data=flights2[,c("dep_delay","arr_delay","air_time","distance")],columns=1:4,title="Datos")

La gráfica que se obtiene es la siguiente:

Scatterplot-flighLa gráfica de arriba solo muestra la relación entre varias variables de los datos no de todas. La información de la gráfica incluye la correlación, la cual muestra que es casi nula entre algunas de las variables y muy próxima a 1 en dos pares de variables. La otra opción es hacer una revisión entre las variables pero no solo usando la correlación, sino la el índice de información Mutua. Este último no solo considera la posible relación lineal, sino también una posible relación no lineal. Para realizar el cálculo en R project se puede usar la librería “entropy”.

Ejemplo en R la información mutua entre arr_delay y distance, es de 0.0406. Lo cual indica que no existe alguna relación que analizar.

Con la breve exploración anterior se puede ir pensando en el tipo de cosas que pueden resultar interesantes o que podían ser modeladas, ejemplo pronosticar conociendo el lugar de despegue la hora y la aerolínea el lugar de arribo, o construir un modelo para clasificar los datos de vuelos por el aeropuerto de origen. Pronosticar la cantidad de vuelos por aeropuerto para el siguiente año, o pronosticar los tiempo de atraso en arribar un vuelo conociendo el origen, el horario, el mes de vuelo y el lugar al cual arribará.

Por su puesto que el tipo de preguntar a responder depende de la persona que está explorando los datos o el negocio que requiere este análisis. Por lo cual en esta entrada solo deseaba mostrar algunos gráficos que se pueden ayudar a explorar los datos, al final la primera parte de realizar algún análisis es explorar aspectos estadísticos básicos y apoyarse de alguna gráfica ayuda a tener alguna visualización de la información.

Análisis similar con Python

 El procesamiento de datos en Python en general es realizado siempre en el módulo pandas, las estructuras de datos para procesar información es similar a R project. Se cuenta con estructuras de datos como Data.Frame y Series, como su nombre lo indica funcionan equivalentemente a las de R.

Se pueden usar en Python algunos de los datos de R project haciendo uso de algún módulo, ejemplo el módulo Stats Models tienen un api para conectarse con los datos de R project, lo cuales se encuentran su lista en Rdatasets.

En el ejemplo lo que hice fue exportar los datos de la librería nycflights13 a un archivo csv y cargarlo en una sección en Pandas de Python.

El código es el siguiente:

#Carga de datos
import pandas as pd
#Cargar datos
flights=pd.read_csv('flights.csv')

Para procesar o explorar la descripción básica de los datos se hacer con los siguientes código.

#Revisión de los datos
#Se ve un resumen de lso datos
flights.head()
flights.shape()

Unas de las cosas estándar al hacer análisis es procesar los missing data, lo cual se puede hacer en python con el siguiente código.

#Revisión
#Un modo burdo de ver que tienen missin values
flights[flights.isnull()!=True].count()
#Nuevo data.frame para los datos sin missin value
flights2=flights.dropna()
flights2[flights2.isnull()!=True].count()

Otro aspecto básico es revisar la descripción de la información de manera general, es decir; revisar aquella variables que son categóricas como origin o dest y también revisar la descripción estadística de variables que pueden ser consideradas continuas, como dep_delay o distance.

#Revisión de algunas variables
#Para conocer la información en general de los datos
flights2.info()
flights2.describe()
#Se exploran algunas de las variables que no son númericas y otras númericas
#Variables continua
flights2['dep_delay'].describe()
flights2['distance'].describe()

#Variables categoricas
flights2['origin'].astype('category').value_counts()
flights2['origin'].astype('category').describe()
flights2['dest'].astype('category').value_counts()
flights2['dest'].astype('category').describe()

Ahora para visar algunas gráficas básicas sobre las variables se usa en general matplotlib, pese a que pandas cuanta con algunas gráficas básicas como histogramas,gráficas de barras y boxplot.

Otra opción de reciente desarrollo es ggplot en python, la cual no cuenta con la misma flexibilidad que en R, pero está en desarrollo. La diferencia entre matplot y ggplot es en esencia que este último fue desarrollado con la perspectiva de “Grammar of Graphics”, mientras que matplot fue pensado en el marco de desarrollo de gráficos  que se usan en matlab. El concepto de ggplot, en recientes años a tomado relevancia ya que se pueden construir gráficos de manera rápida que involucran de fondo una transformación de los datos.

Un ejemplo es el siguiente, el cual se hace con los gráficos de base de pandas.

#Boxplot
df=flights2[['month','origin']]
df.boxplot(by='origin')

Boxplot_por_Mes

El gráfico es similar al que se obtienen en ggplot con R, pero en su defecto en R no se requiere seleccionar los datos y directamente indicar que se agrupen para hacer el gráfico.

Entonces para hacer un análisis gráfico rápido me resulta más fácil pensarlo en R que en Python, pero se obtienen ciertas ventajas en Python que no se obtienen en R.

Otra opción que existe es usar los gráficos de R desde pandas con el módulo rpy2, por medio del cual de cierto modo se usa todo lo que se quiera de R y se utiliza en python.

Un ejemplo de ggplot en Python, usando el módulo para python y no desde R, es el siguiente:

#Gráfica de barras
from ggplot import *


print ggplot(flights2,aes(x='month',fill='factor(origin)'))+\
 geom_bar(color="black")+\
 ggtitle('Barras por cada Mes')+\
 theme(plot_title=element_text(lineheight=2))+\
 ylab('Cantidad de Vuelos por Mes')+\
 xlab('Meses')

Barras_por_mes

El gráfico es parecido al primero que mostré en R. El boxplot de los vuelos en matplotlib se puede obtener del siguiente modo:

#Boxplot Maplotlib
import numpy as np
import matplotlib.pyplot as plt

plt.style.use('ggplot')

fig,ax1=plt.subplots()
ax1.boxplot(Mes,showmeans=True)
ax1.set_title('Boxplot de vuelos por mes')
ax1.set_xlabel('Valores')
ax1.set_ylabel('Meses')
plt.show()

Boxplot de los meses

Los histogramas para explorar el comportamiento de los tiempo de retraso y de despegue se obtienen en ggplot para python se obtienen con el siguiente código.

#Histogramas
from ggplot import *
print ggplot(flights2,aes(x='dep_time',fill='origin'))+\
 geom_histogram(color="black")+\
 ggtitle('Histograma de la hora despegue')+\
 theme(plot_title=element_text(lineheight=2))+\
 ylab('Cantidad de vuelos')+\
 xlab('Horario')

print ggplot(flights2,aes(x='arr_time',fill='origin'))+\
 geom_histogram(color="black")+\
 ggtitle('Histograma de la hora de arribo')+\
 theme(plot_title=element_text(lineheight=2))+\
 ylab('Cantidad de vuelos')+\
 xlab('Horario')

Histograma_despegues

Histograma_arribos

La gráfica del cruce entre los retrasos de arribo y despegue se obtienen de manera similar a la que se realiza en ggplot para R, lo único que se hace notar, es que la librería ggplot para python es más lenta al crear una gráfica con muchos datos.

#Scatter plot
from ggplot import *
print ggplot(flights2,aes(x='dep_delay',y='arr_delay'))+\
 geom_point()+\
 geom_smooth(color="red")+\
 ggtitle('Cruce de retrasos')+\
 theme(plot_title=element_text(lineheight=2))+\
 ylab('Retrasos en arribos')+\
 xlab('Retrasos en despegue')

Cruce_de_retrasos

Para hacer una gráfica similar en matplotlib se observa que el código es más elaborado, se obtiene una gráfica similar pero con mayor cantidad de líneas de programación.

#Ejemplo en Matplotlib
import matplotlib.pyplot as plt

for aero in ['LGA', 'JFK', 'EWR']:
 x =flights2.loc[flights2.loc[:,'origin']==aero,'dep_delay']
 y = flights2.loc[flights2.loc[:,'origin']==aero,'arr_delay'] 
 
 if aero=='EWR':
 color='red'
 plt.scatter(np.asarray(x.values)[:len(x)-1],np.asarray(y.values)[:len(y)-1],
 c=color, label=aero)
 
 if aero =='JFK':
 color='blue'
 plt.scatter(np.asarray(x.values)[:len(x)-1],np.asarray(y.values)[:len(y)-1],
 c=color, label=aero)

 if aero=='LGA':
 color='green'
 plt.scatter(np.asarray(x.values)[:len(x)-1],np.asarray(y.values)[:len(y)-1],
 c=color, label=aero) 
 

plt.legend(loc=4)
plt.grid(True)
plt.title('Scatter plot de los retrasos')
plt.ylabel('Retrasos en despegues')
plt.xlabel('Retrasos en arribos')
plt.show()

La gráfica es la siguiente:

Scatter_plot_retrasos

Otra gráfica fácil de hacer es la del comportamiento de los histogramas de los retrasos, tanto de despegues como de arribos.

El código es el siguiente:

#Histogramas
import matplotlib.pyplot as plt

plt.style.use('bmh')

x =flights2['dep_delay']
y = flights2['arr_delay'] 

x1=np.asarray(x.values)[:len(x)-1]
y1=np.asarray(y.values)[:len(y)-1]
plt.hist(x1, histtype="stepfilled",
 bins=20, alpha=0.8, normed=True)
plt.hist(y1, histtype="stepfilled",
 bins=20, alpha=0.8, normed=True)
plt.title('Histogramas de los retrasos de despeque y de llegada')
plt.xlabel('Valores de los retrasos')
plt.ylab('Cantidad de retrasos')
plt.show()

La gráfica es la siguiente:

Histogramas_de_los_retrasos

Para hacer un panel de gráficos como el de la exploración en R, se tiene que diseñar el panel con el número de gráficos que se desea. Esto en el fondo también sucede con R, solo que en matplotlib uno tiene que hacer el código con mayor detalle.

Espero que estas cuantas gráficas hechas en python de una imagen de lo versátil que es, se requiere en general procesar más los datos pero se puede tener mayor control sobre el tipo de gráficos que se pueden hacer.En la referencia [4] se pueden consultar muchas gráficas de muestra.

Referencias

1.-http://static.googleusercontent.com/media/research.google.com/es//archive/mapreduce-osdi04.pdf

2.-http://www.jstatsoft.org/v40/i01/paper

3.-http://ggplot2.org/

4.-http://matplotlib.org/

5.-http://pandas.pydata.org/pandas-docs/stable/groupby.html

Análisis Confirmatorio vs Exploratorio

Análisis Exploración….¿qué es eso? 

La idea de la exploración de datos es tal cual lo que su nombre indica, es buscar cosas entre los datos.

Inicialmente uno entra a esa selva de datos y paso a paso va siguiendo algún camino o haciendo uno nuevo, cada pequeño avance nos va dando pistas del lugar en el que estamos, y poco a poco nosotros como exploradores vamos entendiendo como es esa selva. La idea creo que es parecida a jugar a descubrir cosas desde los datos. Lo que se intenta es tomar la información y tratar de encontrar algún indicio de algo que puede “servirnos”. Pero, ¿qué es “servirnos”?,¿qué buscamos?,¿para qué queremos entender esa selva?

Puede parecer absurdo, pero un paso clave antes de explorar la información es conocer un poco sobre su origen, el tipo de datos, la cantidad de ellos y cómo se generan. Hacer este tipo de indagación antes de procesarla y explorarla nos puede ayudar a no caer en falsos “descubrimientos”.

Ejemplo; si uno tiene información de las votaciones por casillas y una casilla muestra un comportamiento “anómalo” con respecto al resto, uno puede tratar de explorar la información en busca de una “explicación” solo desde los datos. En ese caso si uno “contextualiza” o revisar el lugar dónde se encontraba la casilla cuando se realizaba la votación, quizás esto puede explicar su anomalía. Ejemplo, si estaba localizada en la sede de uno de los candidatos es probable que explique porque contenía solo votos de él o si se sabe que la localidad es corrupta uno puedo sospechar que todos estaban de acuerdo en votar por un candidato.

Puede parecer que la exploración de datos es algo poco sofisticado, hacer una gráfica no parece ser lo más difícil cuando uno tiene datos de asistencia de los alumnos de una clase de matemáticas en una preparatoria , o el valor de una moneda contra el dolar durante 100 días, o el registro de lo que compran en el supermercado 50 personas el mismo día. Eso no parece un gran problema. Pero cuando uno  tienen “mucha información”, como todas las publicaciones de los Mexicanos en facebook en dos años, o las transacciones de todos los clientes de un banco, o de todas las consultas que se hacen en Google por año (que son actualmente 1.2 trillones de búsquedas); esa cantidad de información ya no resulta tan fácil de pensar en cómo graficarla o cómo empezar a explorarla.

Revisando un poco de historia, Jhon Tukey en el año 1977 publica su libro sobre “Exploración de datos”, mucho años antes de que tuviéramos computadoras personales con la potencia de gráficos que ahora tenemos. En su libro resaltaba que era fundamental el diseñar herramientas simples para realizar una exploración de los datos antes de proceder a construir un modelo o aplicar alguna técnica inferencial. Hace una distinción entre el análisis confirmatorio y el análisis exploratorio, de manera general uno pude pensar que el confirmatorio es un modo deductivo de estudiar los datos y el exploratorio un modo inductivo. Es decir, en el confirmatorio se platea validar una hipótesis, probar una “ley” o algo que explica de manera general el comportamiento de todos los datos analizados. En el exploratorio se busca ir de lo particular a lo general, de unas cuantas variables, de calcular algunas cosas o  hacer ejercicios gráficos  de donde se puede ir concluyendo el comportamiento global de los datos.

En el exploratorio, uno debe tener duda de lo que su mente deduce desde algún gráfico o técnica de visualización, no se debe de concluir inmediatamente solo confiando en los que “vemos”, en lugar de eso uno debe de plantear algunas preguntas, ir mejorando la calidad de la exploración y posteriormente poner a prueba nuestras hipótesis por medio del análisis confirmatorio.

Pero antes de compartir algunos ejemplos de exploraciones, es bueno tener claro a qué me referimos cuando digo “datos”. Ahora que la palabra Big Data o Data Sciences está en boca de todos, se tienen ideas intuitivas de que siempre estamos generando “datos”, ejemplo; cuando publicamos algo en nuestro muro de facebook, cuando subimos algún vídeo, cuando mandamos algún e-mail, cuando enviamos un mensaje a través de una app, cuando hacemos alguna llamada, cuando elegimos alguna película por medio de una plataforma en internet, cuando realizamos alguna búsqueda en google, bing o yahoo. No es falso, efectivamente en cada uno de los casos anteriores  generan datos.

Lo que me parece que imaginamos como “datos” en general es un puñado de números o cifras. Pero no piensa que también lo son los vídeos, mensajes de texto, cadenas alfanuméricas o imágenes.

Lo fundamental es que desde cualquier tipo de dato se pueda obtener información cuantitativa, aunque solo nos parezca que nuestra información es cualitativa, que a primera vista nos parece poco natural como analizar los mensajes de texto, email o fotos.

Con esta explicación trato de decir que siempre se tiene una noción clara de como calcular la media de una colección de números, pero no es claro como asignar algún valor a un texto. Sin embargo, para muchos tipos de datos existen herramientas o métodos de procesamientos por medio de los cuales se pueden explorar y analizar, pero siempre es posible diseñar un nuevo método o indicador.

Ejemplo, en un texto se puede pensar en analizar la frecuencia de las palabras, la longitud de las oraciones, la hora de emisión de texto, compararlo contra otro y poco a poco establecer un modo para clasificar.

Otro problema común es el saber cómo asignar un tipo de distribución a una colección de datos, en ocasiones se asigna alguna conocida debido a que se creé “entender” cual es el proceso que genera esos datos. En algunos casos funciona  bien ese método, ejemplo la distribución de Poisson para modelar las llegadas a la fila del banco o la atención de llamadas telefónicas a un call center. Pero en la mayoría de los casos no es claro qué distribución tiene la información, así que parte importante de la exploración es tener técnicas para encontrar algunas posibles y después ir validando las candidatas con los datos que se  tienen.

Ahora si, Machine Learning y Análisis Exploratorio

Buena parte de las técnicas de Machine Learning (ML) son exploratorias o tienen algo de ello. Entre la clasificaciones de técnicas de ML a las que se refieren como aprendizaje no supervisado, prácticamente puede ser pensado como análisis exploratorio.

Un concepto clave de lo que son los “datos”  para R project, es lo que se llama “matriz” o arreglo bidimensional. En general es como se ordena la información. Entonces se tienen columnas que serán las variables asignadas a cada uno de los elementos de estudio, que están nombrados y ordenados en las filas de la matriz. Ejemplo, en la columna se puede tener las variables: peso, altura, edad, ancho de espalda, ancho de cintura, etc. En las filas, se tienen ordenado como: persona 1, persona 2, persona 3, etc.

Lo anterior, es en la práctica lo deseable. Pero es común que la información no este bien ordenada ni limpia. Por lo cual es importante revisarla, tenerla ordenada antes de iniciar la exploración, eso permite ir conociendo el tipo de datos, el origen y las variables.

Para replicar el primer ejemplo se deben de trasladar por medio de R ( o R Studio) al directorio donde se encuentran los datos o desde la consola de R pasar al directorio correspondiente. Para replicar el ejemplo, supongo que se descargaron los datos del texto Machine Learning for Hackers que se encuentran en GitHub.

#Abrimos los datos
data.file<-file.path("data","01_heights_weights_genders.csv")
heights.weights<-read.csv(data.file)

Esto se puede hacer de otro modo, si solo se cambia uno de directorio. Todo lo hago pensando en que se usa la consola de R project, ya que creo que es base conocerla y después de eso usar R Studio no genera mayor problema.

#Cargamos los datos
heights.weights<-read.csv(01_heights_weights_genders.csv)
head(heights.weghts)

Hago ahora uso de un simple comando para conocer aspectos de los datos, summary, por el cual se obtiene un resumen de la información de las columnas. En el ejemplo se tiene:

  Gender         Height          Weight     
 Female:5000   Min.   :54.26   Min.   : 64.7  
 Male  :5000   1st Qu.:63.51   1st Qu.:135.8  
               Median :66.32   Median :161.2  
               Mean   :66.37   Mean   :161.4  
               3rd Qu.:69.17   3rd Qu.:187.2  
               Max.   :79.00   Max.   :270.0  

En caso de que se tengan bastantes columnas y solo se tiene interés en algunas de ellas, se puede extraer la información con la función with del siguiente modo:

#Elegimos la columna Height
heights<-with(heights.weights),Height)
summary(heights)

En caso de no conocer el nombre de la columna, se puede usar la función head, para ver los nombres antes de extraer la información.

Con summary, se obtendrá el valor de la media, del máximo, del mínimo y la media. Pero se puede calcular directamente el valor del  máximo, el mínimo y le media, con las funciones mean,max,min, aplicadas a la columna de datos “heights”.

Para tener claro que tipo de cosa se busca revisar y con qué funciones, se puede clasificar la exploración en:

  1. Medidas de Localización
  2. Medidas de Dispersión
  3. Medidas de Forma

Medidas de Localización

Entre estas medidas se consideran el calculo de la media, del mínimo, del máximo, la moda, los cuantiles.

Medidas de Dispersión

Entre estas se consideran el rango de intercuantiles, el rango de los datos, la varianza y la desviación estándar.

Medidas de forma

Estas medidas son la asimetría y la kurtosis.

Para cada una de estas medidas se tienen un comando o función en R.

#Medidas de localización para Height
mean(heights)
# Vale la pena revisar los parámetros que se pueden manipular para la siguiente función, así podemos definir los rangos que deseamos ver de los cuantiles
quantile(heights)
#El comando summary presenta un resumen 
summary(heights)

Para las medidas de dispersión se cuenta con:

#Medidas de disperción para Height
range(heights)
IQR(heights)
var(heights)
sd(heights)

Para las medidas de forma uso la librería “e1071“, para lo cual se debe de instalar ya que no está por default en R.

#Medidas de forma para Height
library(e1071)
#También se puede usar la librería moments
skewness(heights)
kurtosis(heights)

Los anteriores conceptos, sobre todo las funciones en R, pueden resultar poco alentadoras para dar idea de como se comportan los datos y si es primera vez con estas cosas, resultan poco claro lo que se hace. La ventaja de R es que cuenta con una gran cantidad de gráficas que permiten entender mejor los conceptos anteriores.

Algunas gráficas en R project para explorar datos

Entre los gráficos más usados para explorar una variable se encuentra el  histograma, la función hist permite obtener el gráfico y cuenta con varios parámetros los cuales pueden ser consultados en el menú de R.

#Construcción del histograma
hist(heights,nclass=20, main="Histograma de las Alturas", xlab="alturas",ylab="Frecuencias", col="red")

Histograma

Se puede conocer un aproximado de la densidad de nuestros datos, en R se puede calcular con la función density.

#Construcción de una gráfica de densidad
plot(density(heights), main="Densidad", xlab="alturas",ylab="Densidad estimada", col="red",type="p")

Densidad
Para mayor conocimiento de las funciones density y plot  recomiendo consultar el menú de R y probar como se pueden modificar detalles como los títulos o agregar otra gráfica. Se puede hacer otro ejemplo con la función plot , para ver la relación entre dos variables de datos hago el ejemplo con pesos(weights) y alturas(heights).

#Construcción de un gráfico con las dos variables
plot(heights,weights, main="Gráfica entre las dos variables", xlab="Alturas",ylab="Pesos", col="green",type="p")

Plot_de_pesos_y_alturas

Un gráfico que me parece importante para explorar las variables y poder estimar distribución de los datos, se construye usando la función ecdf. Esto permite ajustar mediante alguna curva los valores estimados de la distribución y principalmente cuando las colas de las distribuciones presentan cierto comportamiento, les llaman distribuciones de colas pesadas.

#Exploración de la cola de la distribución
f<-ecdf(heights)
range(heights)
[1] 54.26313 78.99874
ttx}) estimada", xlab="Valores de Height", col="6",log="y",type="p")

Colas_de_las_dist

En particular la paquetería de R para gráficos es bastante buena, usando la función layout uno puede construir gráficos más elaborados. Un ejemplo es el siguiente, del cual no explico detalles del código pero pueden consultarse en el manual de R.

#Construcción de gráfico con histogramas marginales
x <- pmin(3, pmax(-3, rnorm(200)))
y <- pmin(3, pmax(-3, rnorm(200)))
xhist <- hist(x, breaks=seq(-3,3,0.5), plot=FALSE)
yhist <- hist(y, breaks=seq(-3,3,0.5),plot=FALSE)
top <- max(c(xhist$counts, yhist$counts))
xrange <- c(-3,3)
yrange <- c(-3,3)
b<-matrix(c(2,0,1,3),2,2,byrow=TRUE)
nf <- layout(b, widths=c(3,1), heights=c(1,3), respect=TRUE)
par(mar=c(4,4,1,1))
plot(x, y, xlim=xrange, ylim=yrange, xlab="x", ylab="y",type="p")
par(mar=c(0,4,1,1))
barplot(xhist$counts,axes=FALSE, ylim=c(0, top), space=0,col="2")
title(main='Scatterplot con histogramas marginales',font=2)
par(mar=c(4,0,1,1))
barplot(yhist$counts, axes=FALSE, xlim=c(0, top),space=0, horiz=TRUE,col="3")

Gráfico_con_layout

Pese a que los gráficos que se tienen por default son buenos, también existen librerías que tratan de mejorar la presentación y manipulación de datos. En breve habla de ggplot, la cual es una librería que no solo está para R project, también existe para Python y es muy recomendable aprender a manipularla, ya que tiene ventajas por que permite ahorrar el proceso de manipular los datos y los gráficos son bastante agradables. En general la librería es bastante madura y cuenta ya con buenas referencias para su aprendizaje.

#Construcción de un histograma con ggplot
ggplot(heights.weights, aes(x = Height)) + geom_histogram(col="2")

ggplot_hist

Al inicio al escribir una gráfica en ggplot parece demasiado enredado comparado con poner solo un comando. Pero con la práctica se empieza hacer notar que además de que la calidad de los gráficos es mejor, se puede diseñar gráficos mucho mas agradables y se tienen mucha libertad para poderlos modificar.

Ejemplo, para revisar las densidades de las alturas con respecto a los géneros resulta mucho más sencillo hacerlo mediante la siguiente indicación.

#Construcción de gráfico de las densidades por género
ggplot(heights.weights, aes(x = Height, fill = Gender)) + geom_density() + facet_grid(Gender ~ .)
ggplot(heights.weights, aes(x = Height, fill = Gender)) + geom_density()

ggplot_densidad_de_h

ggplot_Heights_for_g

Para hacer una gráfica de las alturas vs los pesos, se requiere solo la siguiente línea y además se agrega la tendencia.

#Construcción de gráfica scatterplot
ggplot(heights.weights, aes(x = Height, y = Weight)) + geom_point() + geom_smooth()

ggplot_scatterplot_HW_tendencia

Como muchas técnicas de Machine Learning son para clasificar, un ejemplo sencillo que se pueden hacer es el distinguir las poblaciones por género y buscar la “mejor”  línea que límite esos datos.

#Transformamos los datos para analizar como se comporta y graficamos la recta que divide a entre géneros

#Primero transformamos los datos
heights.weights <- transform(heights.weights,Male = ifelse(Gender == 'Male', 1, 0))
#Ahora claculamos una regresión lineal general
logit.model <- glm(Male ~ Weight + Height,data = heights.weights,family = binomial(link = 'logit'))
#Por último contruimos el gráfico
ggplot(heights.weights, aes(x = Height, y = Weight)) +
  geom_point(aes(color = Gender, alpha = 0.25)) +
  scale_alpha(guide = "none") + 
  scale_color_manual(values = c("Male" = "black", "Female" = "blue")) +
  theme_bw() +
  stat_abline(intercept = -coef(logit.model)[1] / coef(logit.model)[2],
              slope = - coef(logit.model)[3] / coef(logit.model)[2],
              geom = 'abline',
              color = 'red')



ggplot_HW_plano_separador

 Una observación que es crucial en la exploración de datos, es que en ocasiones se requiere que se “transformen”. Con eso quiero decir que si se tiene una gráfica como la anterior, pero donde el rango de los datos en el eje X es muy grande, es posible que sustituyendo los datos originales por su logaritmo se pueden estudiar de modo más “cómodo”. Pero cuando se transforman los datos o se usa alguna transformación, es recomendable considerar que dicha función respete el orden en el cual tienen los datos,  que sea continua y hasta cierto punto “suave”, que tenga sus derivadas. Esto es quizás técnico, pero es importante tenerlo en cuenta.

Espero la entrada sirva para tener una idea general de lo que es la exploración, en buena medida muchas de las técnicas más avanzadas, que van desde generalizaciones de Análisis de Componentes Principales hasta la Homología Persistente  y variedades de aprendizaje son técnicas exploratorias, requieren cierto conocimiento de lo que se hace para que sea fácil la  interpretación de sus resultados y conocer en qué situación es recomendable usar cada técnica.

Referencias:

1.-http://www.amazon.es/Exploratory-Analysis-Edition-Chapman-Computer/dp/1439812209

2.-http://www.amazon.com/ggplot2-Elegant-Graphics-Data-Analysis-ebook/dp/B0041KLFRW

3.-http://www.amazon.com.mx/Introductory-Beginners-Visualisation-Statistical-Programming-ebook/dp/B00BU34QTM

4.-http://www.amazon.es/Graphics-Second-Edition-Chapman-Series/dp/1439831769

5.-http://www.r-bloggers.com/

¿Qué se necesita conocer de R project para aprender algunas técnicas de Machine Learning?

Sobre R

El lenguaje R o R project, en recientes años se ha vuelto muy popular, sobre todo en el ámbito académico y poco a poco empieza a sonar en el sector de la industria de la Tecnologías de la Información (TI).

Tan es así, que Oracle una empresa líder en tecnología y conocida por su gestor de bases de datos con el mismo nombre, ahora ofrece una versión de R dentro de su gestor de bases de datos. No he probado la versión, por lo cual desconozco si tienen todas las funcionalidades iguales o si tienen ciertas restricciones al compararlo con la versión de R que uno descarga libremente.

Si uno busca en la red o en la página principal de R project, se encontrará con la abrumadora noticia de que existen aproximadamente más de 7 000 librerías. Las librerías son un bloque de código o funciones que alguien escribió y compartió libremente para hacer uso de ellas en el software.

Al ser libre R project uno tienen la posibilidad de compartir algunas funciones que considere que son buenas y que a otros les pueden servir, eso hace que una comunidad a nivel mundial esté actualizando librerías o compartiendo nuevos algoritmos.

Entre todas las librerías uno puede encontrar un poco de todo. Se encuentran librerías que permiten la manipulación de datos, realizar conexiones a la red, automatizar pronósticos, manipular y analizar textos, generar reportes, conectarse con gestores de bases de datos, manipular mapas, etc.

Si uno toma alguna técnica  estándar para hacer algo de estadística, es probable que exista más de una librería que nos permite hacer eso. Por lo tanto pretender conocer todas las librerías es una tarea casi imposible y lo que recomiendo es ir consultando en la red, en foros o blog para conocer las librerías que sugieren para realizar tal o cual técnica.  Al final las mejores librerías y las más usadas tenderán a persistir en las recomendaciones que haga la gente.

Existen muchos manuales básicos para aprender a usar R [1,2,3,4,5]. Lamentablemente el manual de introducción en español no ha sido actualizado desde hace años, pero se cuenta con muchas referencias que van desde blog, notas y textos  que cubren prácticamente todo lo que uno debe de saber a un nivel básico o intermedio, y posiblemente hasta un poco avanzado ( hay un libro hermoso de temas avanzados escrito por Hadley Wickham que deben de apurarse a leerlo).

Lo “malo” hasta cierto punto es que las mejores referencias se encuentran en Ingles, es importante aprender por lo menos a leer en dicho idioma pero hace falta en ocasiones manuales en español que clarifiquen los conceptos e ideas.

Al final lo recomendable para aprender cualquier software es practicar, tomar varias fuentes para aprender y replicar ejemplos. Estudiar el código que otros hacen y hacer las modificaciones que uno pueda ir pensando que mejoran dicho código, ya sea para optimizarlo o solo para probar si se puede usar para hacer otra cosa.

Lo que puedo decir es que R project es un software bastante sencillo de aprender,  lo complicado no radica en el software mismo, sino conocer lo que hacen comandos, técnicas, algoritmos y librerías. A gente que lleva toda su vida haciendo software le desconcierta y le parece muy “científico” como para aprenderlo, pero con algo de tiempo y algunas revisiones de como declarar variables, hacer funciones, manipular tipos de datos, etcétera; van perdiendo el miedo a usarlo.

R project y Machine Learning

La instalación en el sistema que sea, Windows, Mac Ox o Linux, son sencillas y el IDE (Entorno de Desarrollo Integrado) es prácticamente igual para todos los sistemas. Lo único que es importante y que cambia es al correr un script desde la consola del sistema. En general la consola de Windows es muy pobre comparada con las de los otros dos sistemas, pero se puede fortalecer usando otros software. Para ese caso en otro momento explico el tipo de cosas que hay que hacer para correr los script.

Un complemente para programar en R es usar el entorno R Studio, que prácticamente es tener un entorno de desarrollo amigable, de mejor vista y con herramientas que simplifican el trabajo al momento de programar en R. Existen  otros entornos, pero es cosa de cuál se adecua mejor a nuestro modo de trabajo y necesidades.

En el caso de los ejemplos de Machine Learning, lo necesario del software se puede clasificar en:

  1. Funciones estándar en R.
  2. Importación, exportación y manipulación de datos.
  3. Funciones particulares de ciertas librerías.

Del primer punto las funciones estándar son: lm, plot, hist, summary, head, apply, sapply, poly, tail, dim, str, names, c, paste, princomp, subset, cov, cor, ts, entre otras. Lo recomendable es revisar por medio de la función help la información de los parámetros y ver algún ejemplo del uso de dicha función, como siempre la recomendación es hacer pruebas para ir mejorando en el manejo de dichas funciones o comandos. Por supuesto que existen más funciones que no menciono, pero son en general las que de momento creo se usan más en las entras.

Sobre la importación y exportación de datos, lo principal en mi opinión es tener claro que el tipo de dato base en R son los vectores o en otras palabras R es un lenguaje “vectorizado” y en general la mayoría de funciones que se usan depende de asignarle data.frame o matrices, que son construidos con vectores.

La importación de los datos se hace por medio de las funciones read.csv, read.txt,scan entre otras. Para este tema se puede consultar un pequeño manual de aproximadamente 30 páginas en la página oficial de R. En general se requiere practicar con la importación de datos, ya que en ocasiones pedir que se importen datos con cierta restricción, como por ejemplo pedir que las cadenas no sean leídas como factores, que se separen las columnas por tabuladores,etc.

Respecto a la manipulación, se cuenta con algunas funciones subset, with, ifelse, cbind, rbind   las cuales son estándar del software. Pero se cuenta con varias librerías que permiten la manipulación de datos, entre ellas, reshape2,  gdata ,data.table, plyr, dplyr.

Del tercer punto, para aprender sobre algunas funciones de ciertas librerías mi recomendación es revisar los manuales de usuarios que son publicados cuando se libera la librería o paquete, es decir; cuando nos permiten usar su código otras personas que usan R project.

La mayoría  de las librerías suelen contar con algunos ejemplos, datos y  en Internet suele haber información casi suficiente para conocer como funcionan. Creo que lo mejor es tratar de replicar los ejemplos, cambiar las condiciones de parámetros y crear un ejemplo, también esto resulta más divertido para comprender lo que hacen las funciones.

Algunas librerías son más populares que otras y en buena medida es por la calidad y utilidad. Ejemplo, la librería ggplot2  es bastante buena para gráficos, se cuenta con libros y notas que explican su uso con buen detalle, además de que en recientes años se ha hecho muy popular y es considerada unas de las herramientas indispensables en análisis de datos.

Otra librería que ha tenido popularidad es tm, que se refiere a Text Mining ( Minería de Textos); se cuenta con bastante información en la red sobre como usar sus funciones con algunas ejemplos, pero además está relacionada con las investigaciones del Procesamiento de Lenguaje Natural (NLP, en ingles).

Por último las librerías que son populares para analizar redes es igraph y sna, con redes me refiero a redes sociales o redes complejas, esta librería cuenta con una gran cantidad de funciones. La gran ventaja es que se cuenta con suficiente explicación y ejemplos debido a la gran popularidad de las redes sociales en nuestro día a día, entonces basta con buscar un poco en la red para encontrar buen material al respecto [6,7].

Espero las explicaciones generen interés en explorar más sobre R project. La última observación que hago es entender que este software permite rápido aprender ciertas técnicas, pero existen otros software que ante proyectos grandes puede ser mejores( Python, C,Ruby, Java, scala), pero sin duda es una buena fuente para aprender practicando,  R lo permite con una curva de aprendizaje muy pequeña.

Comentario: Debido al desarrollo de R y  la creación de nuevas librerías, con el paso del tiempo algunos de los comentarios respecto a las librarías puede dejar de ser actualizado. Ejemplo, ggplot2 ha evolucionado no solo con mejoras y más funciones, sino también con la aparición de otro tipo de librerías que se abocan a la visualización de datos a nivel web. Otro ejemplo es en el procesamiento de datos, debido a la relevancia de plyr y dplyr es posible que aparezcan librerías más optimizadas o con otro tipo de características, ejemplo data.table es mejor para ciertas operaciones con datos. Así que siempre hay que tener en mente que los software evolucionan, pero ello es recomendable conocer de manera solida las estructuras base o herramientas base.

“The best thing about R is  that it was developed by statisticians. The worst thing about R is that….it was developed by statisticians.”  Bo Cowgill, Google, Inc.

Referencias:

1.-The R inferno.

2.-Using R for Numerical Analysis in Science and Engineering.

3.-A handbook of Statistical Analyses using R.

4.-Data Manipulation with R.

5.-R in Action.

6.-Igraph

7.-SNA

8.-R-bloggers

9.-Revolution Analytic