Algoritmos de Machine Learning en R project

“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.

Todas las entradas de esta categoría muestran algoritmos y técnicas clasificadas como algoritmos de Machine Learning o Aprendizaje Estadístico. En cada entrada comparto el código  y algunos repositorios donde pueden bajar datos y notas sobre los temas.

Las ventajas de usar R project para dar estos ejemplos son las siguientes:

1.-R project es software libre u open source, por lo cual cualquier persona pude descargarlo.

2.-El código que comparto solo debe de ser copiado y pegado en un Script o en la consola  de R project para reproducir los resultados.

Otra ventaja de aprender estas técnicas con ejemplos en R, es que muchos de los algoritmos son acompañados de alguna técnica gráfica para visualizar el resultado. R project por default cuenta con una gran cantidad de herramientas gráficas o se puede hacer uso de librerías como ggplot2, lattice, ggvis para hacer gráficas aún más elaboradas y visualmente más agradables.

El entendimiento de la técnica después de realizar un ejemplo desde mi perspectiva genera interés por saber como aplicarla a otros datos y nos invita a conocer más sobre el algoritmo desde un punto de vista no solo práctico, sino también teórico.

Evité en la medida de lo posible hacer uso de ecuaciones y en cada ocasión que se menciona algún concepto de matemáticas trato de explicarlo de un modo sencillo. Si este concepto requiere a mi parecer una mejor lectura, agregue algunas ligas para consultar en la red.

La única meta que me propuse fue explicar las cosas de modo tal que cualquier persona con un poco de curiosidad pueda entender algo de cada entrada.

Teniendo en mente lo anterior, espero que  el objetivo de trasmitir el conocimiento desde un ejemplo concreto haya sido logrado. En caso de que no sea así, sería grato saber qué parte no es clara y como mejorar este material.

Resumen de las entradas.

El orden siguiente es el que considero apropiado para revisar cada entrada.

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

Es una breve explicación sobre R project y sobre algunas de las funciones con las que cuenta por default. También menciono las librería que se requieren para replicar los ejemplos, aunque en cada entrada menciono algo breve sobre la librerías requeridas.

2.-Análisis Confirmatorio vs Exploratorio

Explico la diferencia entre los dos tipos de análisis y cómo están relacionados. Clasifico el tipo de medidas que uno puede analizar en los datos y pongo algunos ejemplos del tipo de gráficas que pueden ayudarnos a visualizar las medidas al momento de explorar la información.

3.-Regresión Lineal, un ejemplo sencillo.

Esta técnica es muy sencilla de implementar y los datos que nos regresa el comando en R debe ser entendidos para poder evaluar la calidad del resultado obtenido. Omito detalles formales del tema y comparto algunos ejemplos de regresiones simples y múltiples. Es un tema con muchos detalles importantes, por ejemplo la revisión de las posibles fallas al construir un modelo lineal o multilineal. No toco mucho  esos temas, pero en las referencias pueden encontrar observaciones y técnicas para conocer más al respecto.

4.-Regresión no lineal, Cross-Validation y Regularization. 

Los tres temas pueden haber requerido una entrada para cada uno, pero funciona bien mostrar como se relacionan. El objetivo es mostrar la implementación de la regresión no lineal y validar que el modelo elegido es el adecuado, para evitar la sobre estimación de los datos. En esto último las cross-validation y la regularización ayudan a tener un método para hacer una elección del modelo. Se dan algunos ejemplos del uso de los tres conceptos y técnicas.

5.-Clasificación binaria….Naive Bayes. 

Es uno de los algoritmos más usados por sencillo y por que puede ser modificado para tener una clasificación rápida en varias categorías. Doy el ejemplo clásico sobre detección de Spam y trato de complementarlo con el uso de una librería en la cual se cuenta con una función para estimar el modelo. Agregué una pequeña explicación sobre la probabilidad condicional y sobre el uso de la librería tm para analizar textos en R project. Espero ser claro y que permita comprenderse el ejemplo.

6.-Análisis de Cluster, un ejemplo sencillo. 

Se explica de modo breve como funciona la detección de Clusters. Como el tema requiere hacer uso de la noción de distancia o métrica, trato de explicar el concepto. Omití mucho material, sobre todo en el uso de distintas métricas para distintos tipos de variables.

7.-Un ejemplo sencillo sobre Análisis de Componentes Principales (PCA, Principal Component Analysis).

La técnica es muy usada y conocida para hacer reducción de dimensiones, explico qué es reducir dimensiones y como interpretar los resultado de la técnica. Como ejemplo principal hago una reducción de 25 indicadores para formar uno que resuma la información del resto. Replico un ejemplo de análisis de la digitalización de los números escritos a mano, este es un ejemplo clásico y la base de datos fue objeto de estudio para comparar técnicas de clasificación.

8.-Sobre sistemas de recomendación, ejemplo sencillo. 

Hago un breve ejemplos de un sistema de recomendación usando la técnica de k-vecinos cercanos (K-nn), esta técnica es no-paramétrica. Para ejemplificar como funciona pongo un ejemplo inicial y trato de explicar qué realiza el algoritmo y aplicarlo a un caso concreto. Los sistemas de recomendación prácticamente dan la libertad de elegir la técnica de clasificación que uno considere adecuada para el tipo de datos o servicio, por lo cual existen libertad de replicar este ejemplo haciendo uso de otro técnicas de clasificación.

9.-Optimización.

Esta entrada creo que es extensa y puede ser un poco amplia,ya que traté de explicar desde aspectos básicos de mínimo y máximos hasta algoritmo estocásticos y genéticos. Puse un ejemplo de como usar el código y en los casos más sofisticados, la parte estocástica, comparto un ejemplo que permitiera comparar los resultado obtenidos con diversos tipos de algoritmos, no puse los tiempos que tardan en dar la solución pero en caso de replicarlos será notorio el costo del procesamiento.

10.-Máquina de soporte Vectorial (SVM-Sopport Vector Machine).

La técnica sumamente usada y funciona bien para datos no-lineales, se dan varios ejemplos de como usar dos librerías que permiten calcular SVM con distintos kernels. En uno de los ejemplos de hace la comparación de varios modelos para determinar por medio de MSE cual es el mejor. Son ejemplos muy sencillos y trato de agregar explicaciones a cada ejemplo.

Lo que no está aún en estas entradas, pero que estará en inicio de Marzo 2016.

Dejé fuera por el momento varios temas fuera de las entradas, ejemplo Redes neuronales , Arboles de decisión, Random Forests, AdaBoost. Espero posteriormente agregar entradas sobre esos algoritmos.

En general todos las entradas tratan de simplificar y resumir lo que se puede encontrar en el texto  “Machine Learning for Hackers“, libro escrito por Jhon M. White y Drew Conway. Si bien, el libro en si es sencillo y requiere un bajo nivel de matemáticas para estudiarse, traté de hacer más sencillas las explicaciones y de complementarlo con otros ejemplos.

La recomendación es complementar las explicaciones de las entradas con la lectura del texto.  Jhon M White compartió su código  y datos usados en los ejemplos en el repositorio Github y pueden descargar el código presionando estas letras en rojo.

Algunos de los códigos deben de revisarse ya que las librerías que usaron en el año de la edición del texto ya fueron actualizadas, por lo cual es generan algunos errores.

Dos temas que vienen en el texto y decidí omitir son generación de un rango y análisis de redes sociales o de grafos. En otro momento comparto ejemplos respecto al tema.

El segundo es sumamente interesante; análisis de redes sociales, pero el código con el que cuenta el texto ya no es funcional. Así que se requiere rehacer buena parte del código y diseñar nuevos ejemplos, para eso se necesita cierto tiempo. Más aún debido al boom de las redes sociales existen otro tipo de herramientas sobre las cuales se puede escribir.

Para tener una idea de lo nuevo e interesante se pueden consultar las siguientes ligas para echar un vistazo:

Deseo que el material que se encuentra en esta categoría les sea útil y sobre todo les deje con ganas de aprender más al respecto y no solo desde el lado aplicado, sino también desde el lado teórico.

En la siguiente cita aplique “instrumento= algoritmo”.

“Tienes que aprender a tocar tu instrumento. Después debes practicar, practicar y practicar. Y después, cuando finalmente estás en el escenario, olvídalo todo y ulula.” Charlie Parker

 Nota: Todas las críticas y comentarios respecto a las entradas son bienvenidos.
Anuncios

Un ejemplo sencillo sobre Análisis de Componentes Principales (PCA, Principal Component Analysis)

En general la técnica  de Análisis de Componentes Principales ( PCA) se usa para reducir la “dimensión” de los datos, con dimensión me refiero a la idea de “coordenadas” o “número de variables”.

Ejemplo, lugar en una habitación tienen tres coordenadas (x,y,z). Para otro caso, las coordenadas o características pueden ser peso, edad, lugar de nacimiento, nombre, altura, años de estudio; lo cual hace que las dimensión sean 6. Es una idea burda de dimensión, espero se aclare con los ejemplos.

En caso de que se tengan conocimientos de álgebra lineal, la dimensión es tal cual la dimensión de nuestro espacio vectorial formado con las variables de nuestros datos.

En la mayoría de problemas de análisis de datos es común que los datos no tengan solo dimensión 2 o 3. Por lo cual se tienen muchos desarrollos teóricos para afrontar los problemas multi-dimensionales.

La técnica que reviso es PCA y forma parte la teoría de  “Análisis de Variables Latentes” o “Análisis Factorial“. Este tema requiere una entrada que explique los detalles teóricos, lo cual pondré posteriormente en la categoría “Sobre Machine Learning”.

La idea  de PCA es reducir o proyectar nuestra información a un espacio de dimensión menor, pero también puede servir para construir un indicador. Este será el ejemplo central de esta entrada.

Una observación fundamental es que  PCA es efectivo cuando la correlación entre variables es alta, es decir; la linealidad entre nuestras variables no es cero.

El modelo parte de tener una matriz de datos  de entrada X (filas y columnas) y se busca un modelo Y=XT  tal que los vectores de salida Y  no estén correlacionados. Esto en álgebra lineal es hacer análisis del espectro de la matriz, que es el estudio de los vectores y valores propios.

Si no se tiene conocimiento de ese tema y los nombres resultan raros, lo recomendable es dar una ligera leída al tema y replicar algunos ejercicios sobre el cálculo de los vectores y valores propios, ellos dan mucha información de la matriz  y son fundamentales para esta y otras técnicas de análisis de datos.

Algunas preguntas básicas sobre PCA son: cómo analizar los datos con la matriz de covarianzas o de correlaciones, qué criterio usar para elegir la cantidad de componentes principales, cómo hacer inferencia estadística, cómo modificar el modelo o técnica para el caso en que no hay mucha correlación entre los datos de entrada.

No explico los detalles teóricos de las respuestas a las cuestiones anteriores, pero en la medida de lo posible trato de indicar y comentarlo con los ejemplos la solución a dichas cuestiones.

Ejemplos de PCA en R project

Como primer ejemplo considero una muestra con 100 participantes en un estudio, de las cuales de mide su peso, altura, ancho de hombros y ancho de caderas. Suponemos que se tienen las siguientes medidas:

Media de peso=54.2, media de altura=161.7,media de ancho de hombros=36.5, media de ancho de caderas=30.1

#Suponemos que tenemos los datos en R 
>S
        x1    x2   x3   x4
[1,] 44.70 17.79 5.99 9.19
[2,] 17.79 26.15 4.52 4.44
[3,]  5.99  4.52 3.33 1.34
[4,]  9.19  4.44 1.34 4.56
#La matriz de covarianzas

Para determinar los compones principales solo  se necesita calcular los vectores y  valores característicos de la matriz S, esto se puede hacer sencillamente en R con un sola función.

#Calculamos los eigenvectores 
eigvectores<-eigen(S)
#Vemos los valores y vectores propios calculados
eigvectores
$values
[1] 58.482924 15.479064  2.541130  2.236882

$vectors
          [,1]        [,2]        [,3]        [,4]
[1,] 0.8328499  0.50952549 -0.18827082  0.10629617
[2,] 0.5029292 -0.85525961 -0.02026013  0.12321841
[3,] 0.1362074 -0.05883247 -0.11146741 -0.98262978
[4,] 0.1867372  0.07384800  0.97556068 -0.08920236

Entonces se puede determinar que el primer vector propio calculado determina el 74.2% de la variabilidad de los datos y junto con el segundo determina el 93.9% de variabilidad. Esto es calculado sumando nuestros valores propios y viendo el promedio que representa cada valor respecto al valor total de los valores propios, claro considerando el orden del primer valor propio al último.

Se puede visualizar gráficamente el peso de los valores propios con la gráfica siguiente.

Valorespropios_ejemplo1

Por lo tanto los componentes principales quedan descritos como:

Y1=0.83X1+0.50X2+0.13X3+0.18X4

Y2=0.5X1-0.85X2-0.05X3+0.073X4

La interpretación del modelo implica que el primer componente principal es un componente de tamaño y el segundo es un componente de forma. Las variables X1,X2,X3,X4 son los datos. peso, altura, ancho de hombros y ancho de caderas. También se puede observar que se redujo la dimensión de los datos de 4 dimensiones (X1,X2,X3,X4) a 2 dimensiones (Y1,Y2).

En el siguiente ejemplo muestra otro modo de usar PCA, por medio de la técnica se analiza un conjunto masivo de datos. Los datos corresponden a 25 indicadores y se quiere obtener uno indicador que represente el comportamiento global y que refleje la variabilidad de la información.

La información para replicar el ejemplo se puede descargar desde el repositorio Github de Jhon M. White, los datos corresponden al capítulo 8.

Para esto se considera que ya se tiene la información de algún modo ordenada o procesada o en su defecto se debe de hacer antes de PCA. Esto implica construir una matriz de datos y además haber explorado dos aspectos; que no se cuente con datos NA en la información y por otro lado podemos reajustar la muestra en caso de que uno de los 25 indicadores no aporta información al análisis.Esto último implica hacer un análisis de los datos, exploración de la información, lo cual es siempre el primer paso antes de aplicar cualquier algoritmo.

Podemos separar el ejemplo en 3 pasos:

  1. Cargar los datos y construir una matriz con ellos.
  2. Confirmar que existe correlación entre los indicadores.
  3. Aplicar PCA.
#Cargamos los datos  
data.file<-file.path("data","stock_prices.csv")
precios<-read.csv(data.file)

#Revisamos como se cargaron los datos
head(precios)

#Cargamos la librería "lubridate" 
library(lubridate)

# Cambiamos el tipo de dato de las fechas
precios<-transform(precios,Date=ymd(Date))

#Cargamos la librería "reshape"
#Construimos una matriz
data.stock.matrix<-cast(precios, Date~Stock,Value='Close')

Lo que se hace con la función ymd es cambiar el tipo de dato pero manteniendo el formato año, mes y día. Con la función cast se construye una matriz la cual toma como columnas las fechas y Stock, carga como valores en las entradas los datos del cierre o ‘close’. Esto se puede ver comparando head(precios) y head(data.stock.matrix).

Revisando la información se detectar que se tienen datos con NA en la fecha 2002-02-01, por lo cual no considera esa fecha y también eliminaremos el indicador DDR, para mostrar como se reajustaría la muestra.

#Eliminamos una fila y una columna  
precios<-subset(precios, Date != ymd('2002-02-01'))
precios<-subset(precios,Stock!=DDR)

#Construimos de nuevo la matriz
data.stock.matrix<-cast(precios, Date~Stock,Value='Close')

Lo que ahora se necesita saber es si existe correlación entre los vectores de entrada X, lo que se suele hacer como idea gráfica rápida es un scatter-plot de panel, es decir; un scatter-plot de cada indicadores con respecto a otro. En este caso son muchas variables lo cual hace complicado detectar a simple vista si existe o no correlación entre nuestros vectores de datos o indicadores.

Lo que se hace es calcular la correlación o matriz de correlación y observar su distribución, eso dará idea de si existe o no correlación, ya que PCA solo funciona bien se cuenta con correlación entre los vectores de entrada.

#Calculamos la matriz de correlación 
cor.matrix <- cor(data.stock.matrix[, 2:ncol(data.stock.matrix)])
correlations <- as.numeric(cor.matrix)
ggplot(data.frame(Correlation = correlations),aes(x = Correlation, fill = 1)) + geom_density()+theme(legend.position = 'none')

Matriz_de_correlaciones

Se aprecia el comportamiento de la densidad  y los datos muestran correlación. Para calcular PCA en R basta con usar la función princomp, la cual está por default en el software.

#Calculamos PCA 
pca<-princomp(data.stock.matrix[, 2:ncol(data.stock.matrix)])
pca
componentes.principales <- pca$loadings[, 1]
loadings <- as.numeric(componentes.principales)
#Graficamos los componentes
ggplot(data.frame(Loading = loadings),
  aes(x = Loading, fill = 1)) +
  geom_density() +
  theme(legend.position = 'none')
#Construimos el indicador
market.index <- predict(pca)[, 1]

grafica_componentes_principales

Así que para comparar el indicador con otro, se poden usar los datos del índice Dow Jones, pero necesito cargar los datos, revisarlos, transformarlos y eliminar la información que no sea necesaria para después construir un data.frame con el indice creado y los datos del Dow Jones, y así tener una comparación entre los indicadores.

#Cargamos los datos del Dow Jones
dji.prices<-subset(dji.prices,Date>ymd('2001-12-31'))
dji.prices<-subset(dji.preces,Date!=ymd('2002-02-01'))
#Elegimos los datos que requerimos
dji<-with(dji.preces, rev(Close))
dates<-with(dji.preces,rev(Date))

#Contruimos el data.frame que necesitamos
comparacion<-data.frame(Date=dates,Indice_Mercado=market.index,DJI=dji)

Si se grafica se obtiene que la relación es “negativa”, entonces se procede a cambiar el valor del índice, es decir, multiplicamos por “-1”.

#Multiplicamos por -1 nuestro índice
comparacion<-transform(comparacion,Indice_Mercado=-1*Indice_Mercado)
ggplot(comparison, aes(x = Indice_Mercado, y = DJI))+geom_point() + geom_smooth(method = 'lm', se = FALSE)

Comparación_DJ_Ivs_ndex

Comparación_DJ_Ivs_ndex_1

Se observa que no es tan malo el indicador al compararlo con el comportamiento del índice Dow Jones en el mismo periodo de tiempo.

Algo sutilmente no mencioné es que se ajusta a una escala los datos del indicador para que la comparación pueda ser visualizada, es decir; si se preserva el comportamiento del indicador pero no sus valores originales. Esto es común en el análisis de datos, se “rescalan” los datos para poder comparar comportamientos de la información.

Un tercer ejemplo se muestra con los datos “hardwritten digits”, los cuales son una muestra clásica de la digitalización de los números del 0 al 9, como los de la imagen siguiente:

14.4

Los datos que se cargarán representan al número 3 digitalizado, al realizar la ditalización la imagen se transforma en una matriz numérica donde cada entrada representa un valor para la escala de grises.

Esta matriz tiene 658 renglones que representan los 658 números 3  de muestra y 258 columnas que corresponde a la matriz de grises, que está formada por una escala de 16*16, es decir 258 columnas.

Replico el ejemplo que se estudia en capítulo 14 del la referencia [2]. Esto se puede replicar para cualquier otro número, hago el ejemplo de ese texto para comparar los resultados con los del libro.

Los datos se pueden descargar desde el repositorio siguiente:

http://statweb.stanford.edu/~tibs/ElemStatLearn/datasets/zip.digits/

#Calculamos los PCA por medio de SVD y princomp
#Cargamos los datos

data=read.table("http://statweb.stanford.edu/~tibs/ElemStatLearn/datasets/zip.digits/train.3 ,"sep=',')

#Revisamos las dimensiones de la matriz de datos
dim(datos)

#Calculamos PCA
pca=princomp(datos_3)

#Graficamos los dos primeros componentes
plot(pca$scores[,1],pca$scores[,2],main="Gráfica de los dos primeros componentes principales",col="6")
abline(h=0,v=0)

#Explicación de la variabilidad por PCA 
plot(pca,col=3,main="Comportamiento de los Componentes Principales")

#Calculamos PCA por medio de SVD

pca2=svd(datos)

#Primeros dos componentes principales obtenidos de SVD
prc1=pca2$u[,1]*pca2$d[1]
prc1=pca2$u[,2]*pca2$d[2]

plot(prc1,prc2,main="Gráfica de los dos primeros componentes principales obtenidos de SVD",col="6")
abline(h=0,v=0)

 Ejemplo_3_pca

Ejemplo_3

 

 Lo que hace el código anterior es calcular los componentes principales por dos vías, es decir; por el algoritmo usual y por la descomposición SVD, que significa “Descomposición de Valores Singulares”. Esto provienen de teoría de matrices y la consecuencia es que podemos obtener los componentes principales de otro modo y también se puede revisar la variabilidad explicada por ellos. Se pueden revisar los detalles completos en la referencia [2] y un ejemplo práctico en [5].

Lo que se obtienen al hacer los cálculos es que de los 258 componentes, para explicar el 96% se puede recurrir a solo los primeros 90 componentes. Lo cual puede interpretarse como un ejemplo de reducción de dimensiones, donde  se pasa de 258 a 90.

Cuando las columnas de la matriz de entrada no muestran correlación, la técnica que se puede emplear es una variación de PCA, el método  ICA.

Una librería para calcular ICA y que fue liberada recién en el 2015 la actualización, es fastICA. Un ejemplo sencillo es extraer de dos señales que se mezclan una estimación por medio de ICA, pese a que ICA también puede ser formalmente estudiada desde las perspectiva de variables latentes y la teoría de información mutua, estos dos temas teóricos tienen relación con otro indicador más joven pero igual de interesante, MIC.

#Generamos dos señales
S<-rbind(sin(1:2000)/20),rep((((1:200)-100)/100),5))
A<-matrix(c(0.291,0.6557,-0.5439,0.5572),2,2)
X<-S%*%A
a<-fastICA(X,2,alg.typ="parallel",fun="logcosh",alpha=1,method="R",row.norm=FALSE,maxit=200,tol=0.0001,verbose=TRUE)
par(mfcol=c(2,3))
plot(1:2000, S[,1 ], type = "l", main = "Señales Originales",
xlab = "", ylab = "")
plot(1:2000, S[,2 ], type = "l", xlab = "", ylab = "")
plot(1:2000, X[,1 ], type = "l", main = "Mezcla de Señales",
xlab = "", ylab = "")
plot(1:2000, X[,2 ], type = "l", xlab = "", ylab = "")
plot(1:2000, a$S[,1 ], type = "l", main = "Estimaciones de ICA",xlab = "", ylab = "")
plot(1:2000, a$S[, 2], type = "l", xlab = "", ylab = "")

Lo que se obtiene son dos señales, las cuales se recuperan desde la mezcla.

ICA_ejemplo

Espero esta breve introducción y los ejemplos ayudan a entender un poco las idea del análisis de componentes principales. Deseo más adelante complementar esta entrada y agregar otros detalles.

Referencias:

1.-http://shop.oreilly.com/product/0636920018483.do

2.-http://statweb.stanford.edu/~tibs/ElemStatLearn/

3.-http://www-bcf.usc.edu/~gareth/ISL/

4.-http://mitpress.mit.edu/books/machine-learning-2

5.-http://genomicsclass.github.io/book/pages/pca_svd.html