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.

Sobre sistemas de recomendación, ejemplo sencillo.

Sobre los sistemas de recomendación

Los sistemas de recomendación son quizás una de esas cosas con las cuales todos tenemos contacto actualmente, van desde sistemas sofisticados y predictivos, hasta otros menos rebuscados que solo nos hacen una lista fija de sugerencia. Los ejemplo conocidos son youtube, spotify, los sistemas de facebook, amazon, Netflix,etc.

Pese a que no es un tema fijo o algo que aparezca como tema dentro de las referencias importantes de Machine Learning, existen algunas referencias que hablan sobre el tema [2] y en particular un laboratorio reconocido por su investigación en sistemas de recomendación es GroupLens de la Universidad de Minnesota.

Este tipo de sistemas se hicieron famosos gracias a la competencia de Netflix,  en la cual un equipo logró cumplir con el reto de minimizar un indicador estadístico para asegurar que se obtenían mejores sugerencias [3]. Existen mucho artículos respecto a este concurso y sobre el sistema que se desarrollo, pero lo que se debe de resaltar es que el equipo ganador no hizo solo de un algoritmo de Machine Learning, uso varios y la parte más importante fue el pre-procesamiento de los datos [4].

Sobre el ejemplo

El siguiente ejemplo de sistema de recomendación lo presento como se discute el texto Machine Learning for Hackers [1]. En el ejemplo se hace uso de la técnica k-Nearest Neighbor(Knn) para definir las recomendaciones, es un método de clasificación no paramétrico. Antes de explicar un poco sobre Knn hago un ejemplo sencillo sobre series de tiempo y principalmente sobre la estimación de la “regresión de k-vecinos cercanos“.

#Regresión Vecinos Cercanos
Mortalidad<-scan("data/cmort.dat")
t=1:lenght(Mortalidad)
#Usamos la función supsmu
plot(t,Mortalidad,col="4",main="Mortalidad por semanas",xlab="Semanas",ylab="Número de muertes")
lines(supsmu(t,Mortalidad,span=0.5),col="2")
lines(supsmu(t,Mortalidad,span=0.01),col="4")

Ejemplo_Regresión_vecinos_cercanos

En la gráfica se observan dos curvas cercanas a los datos que están en color verde.Observando con detenimiento la curva en rojo se parece mucho a la línea de tendencia de los datos, pero no es tal cual una recta. Por otro lado la curva en azul, parece más cercana a una descripción del comportamiento “real” de los datos. En ambos casos lo que se hace es ir calculando una regresión para cierta cantidad de vecinos cercanos a cada punto, la línea roja se calcula para una cantidad mayor de vecinos en cada punto y la azul para una cantidad menor, por ello la línea roja no es una recta del todo y la azul tiene pequeños picos y a la vista nos parece mejor para describir los datos.

La gráfica anterior dice que cuando se calcula la regresión o el mejor ajuste lineal para una cantidad mayor de vecinos se tiende a seguir la tendencia de los datos. Cuando se calcula para una cantidad menor de vecinos es probable que la curva siga de cerca el comportamiento de los datos. Con este ejemplo solo deseo mostrar que Knn es hasta cierto punto útil para hacer exploración de la información y que si bien este caso es una regresión, la idea en general es la misma de considerar los vecinos cercanos. Esto de que “parezca” muy parecido a los datos tienen un costo  en el sentido estadístico en caso de considerar dichos algoritmos como candidatos para implementación.

Una imagen burda del algoritmo Knn es pensar en que si se está localizado en uno de los datos en color verde  se traza un circulo centrado en ese punto y se cuenta la cantidad k vecinos para luego hacer la regresión. Lo que se debe de resaltar es que trazar un circulo implica hablar de una distancia para comparar qué puntos están dentro o no del circulo, igual que en el análisis de Cluster se requiere la noción de distancia en el algoritmo de Knn.

Hago un ejemplo solo para mostrar como funciona la librería class que contiene la función knn que permite hacer el cálculo de k-vecinos cercanos. Tomo un subconjunto de entrenamiento y uno de prueba, estimo el modelo para el conjunto de datos de entrenamiento y comparo el resultado con los datos de prueba. Hago una comparación de un método lineal paramétrico de clasificación ( regresión logística) con respecto al método Knn.

Los datos empleados se pueden descargar desde github.

#Comparación de métodos
data.path<-file.path("data","example_data.csv")
datos<-read.csv(data.path)
n<-1:nrow(datos)
set.seed(1)

#Tomamos el 50% de los datos
library(class)
indices<-sort(sample(n,50))
training.x<-datos[indices,1:2]
training.y<-datos[indices,3]
test.x<-datos[-indices,1:2]
test.y<-datos[-indices,3]
#Aplicamos el método Knn
prediccion<-knn(training.x,test.x,training.y,k=5)
sum(prediccion!=test.y)
#Aplicamos un método lineal logit
modelo.logit<-glm(Label~ X+Y,data=datos[indices,])
prediccion2<-as.matrix(predict(modelo.logit,newdata=df[-indices,])>0)
sum(prediccion2!=test.y)

Se observa que en el ejemplo el método Knn da como predicción un 88% de coincidencias y el método lineal solo el 60%. Así que para situaciones no lineales se puede usar con mejor eficiencia el método Knn. Cuando digo predicción, me refiero a cuantos de los puntos de prueba el método clasificó correctamente y cuantos no.

Ejemplo de sistema de recomendación

Para el ejemplo se toma un conjunto de datos respecto a los paquetes instalados en R project. La intención de detectar de una lista de paquetes instalados cuando un usuario va  instalar otro paquete sabiendo cuales tiene instalados. Fue parte de una competencia en Kaggle. Lo interesante es ver que con una muestra pequeña se pudo aprender del comportamiento de los usuarios caracterizados por los paquetes instalados.

#Revisión de paquetes instalados
data.path<-file.path("data","isntallations.csv")
instalaciones<-read.csv(data.path)
#Revisamos las cabeceras
head(instalaciones)
#Construimos una matriz de datos
library(reshape)
matriz.de.paquetes<-cast(instalaciones,User~Package,value='Installed')
#Modificamos las filas 
row.names(matriz.de.paquetes) <- matriz.de.paquetes[, 1]
matriz.de.paquetes <- matriz.de.paquetes[, -1]
#Matriz de similitud
matriz.similitud <- cor(matriz.de.paquetes)
#Definimos una distancia
distancia <- -log((matriz.similitud / 2) + 0.5)

#Calculamos los vecinos cercanos
k.nearest.neighbors <- function(i, distancia, k = 25)
{
 return(order(distancia[i, ])[2:(k + 1)])
}

#Función para estimar la probabilidad
prob.instalacion <- function(user, package, matriz.de.paquetes, distancia, k = 25)
{
 neighbors <- k.nearest.neighbors(package, distancia, k = k)
 
 return(mean(sapply(neighbors, function (neighbor) {matriz.de.paquetes[user, neighbor]})))
}

#Función para elegir los paquetes más probables de isntalar
paquetes.mas.prob <- function(user,matriz.de.paquetes, distancia, k = 25)
{
 return(order(sapply(1:ncol(matriz.de.paquetes),
 function (package)
 {
 prob.instalacion(user,package,matriz.de.paquetes,distancia,k = k)
 }),
 decreasing = TRUE))
}

user <- 1

listing <- paquetes.mas.prob(user, matriz.de.paquetes, distancia)

colnames(matriz.de.paquetes)[listing[1:15]]
 [1] "adegenet" "AIGIS" "ConvergenceConcepts" "corcounts" "DBI" "DSpat" "ecodist" 
 [8] "eiPack" "envelope" "fBasics" "FGN" "FinTS" "fma" "fMultivar" 
[15] "FNN" 

Explico en lo general los pasos del código anterior. Primero  se cargan los datos que se encuentran en formato “csv”, luego se transforman a una matriz lo cual se hace con la función cast de la librería reshape. Una vez transformados, se calcula su matriz de correlaciones, pero la observación es que el método Knn no funciona con la matriz de correlaciones, sino con la matriz de distancias o similitudes.

El paso clave es usar el logaritmo y definir una distancia mediante la “normalización” de los valores obtenidos en la matriz de correlaciones, este paso es crucial para poder aplicar el algoritmo. Espero se pueda entender este paso, lo que se hace es considerar que las correlaciones tienen valores entre -1 y 1, suponiendo que no se alcanza el valor -1, entonce el intervalo de posibles valores tienen longitud 2. Si dividimos cada valor de la correlación sobre 2 y después se le sumamos 0.5, obligamos a que los valores estén entre 0 y 1. El logaritmo , de hecho el negativo del logaritmo con valores entre 0 y 1 indicarán que cuando los valores se aproximen a cero indica que son más distantes los paquetes de los usuarios  y que cuando se aproximen a 1 son muy cercanos.

Por último define una funciones que permite estimar la probabilidad mediante el cálculo de Knn. Entonces se obtiene una matriz la cual permite conocer cuales son los paquetes con mayor probabilidad para poder recomendarlos al usuario. La última línea muestra los 15 paquetes con mayor probabilidad de recomendar al usuario 1.

Entonces construir un sistema de recomendaciones es prácticamente tener una versión de este tipo de algoritmos o de este tipo de técnicas en el sistema, pero como lo mencioné al inicio de la entrada no existe un solo algoritmo útil para estos sistemas ya que se puede recurrir a varios para determinar cual funciona de manera adecuada. Ejemplo, si los datos muestran un comportamiento lineal es preferible usar la regresión logística que knn ya que clasificará mejor los datos.

Puede parecer confuso lo que hago en el ejemplo, pero en resumen es lo siguiente:

  1. Se cargaron los datos.
  2. Se construye una matriz de correlaciones con la información de los paquetes instalados en cada usuario.
  3. Se define una matriz de distancia por medio de la matriz de correlaciones.
  4. Se aplica el método Knn, el cual estimará los paquetes más cercanos a cada usuario.

Faltaría diseñar una interfaz agradable para mostrar los resultados.

Referencias:

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

2.-http://www.mmds.org/

3.-http://www.wired.com/2009/09/bellkors-pragmatic-chaos-wins-1-million-netflix-prize/

4.-http://www.netflixprize.com/assets/ProgressPrize2008_BigChaos.pdf