lunes, mayo 26, 2014

Primeros pasos con machine learning usando Mahout... Un recomendador de productos

Recomendador de productos

Lo que vamos a hacer con Apache Mahout es el "Hello World" del machine learning: un recomendador de productos. En esencia, un recomendador de productos compara los productos que le gustan a un usuario con usuarios que gustos similares para recomendar al primero un producto similar basándose en los gustos del segundo.

Dicho con un ejemplo: Pongamos que:

A Jaimito le gustan los Refrescos de Cola y no le gustan los Batidos de chocolate.
A Pepito le gustan los Refrescos de Naranja y no le gustan los Batidos de Vainilla.
Entonces nuestro programa de machine learning podría decir que a Jaimito le podrían gustar los refrescos de Naranja, ya que le gustan los refrescos, por lo que le recomendaríamos la Fanta Naranja.

Esto, aunque sea una explicación un poco arcaica e inexacta, es una manera fácil y rápida de entender cómo funciona un recomendador de productos a través de machine learning. Ya habrá tiempo de ponerse purista :D

Descargando e instalando Mahout

  1. Web oficial: http://mahout.apache.org/
  2. Release a utilizar 0.9

cd $HOME
tar -zxvf mahout-distribution-0.9.tar.gz

Creando la clase del recomendador


public class MlMain {

 public static void main(String[] args) throws IOException, TasteException {
  //String pathToCsvFile = "/var/hadoop/examples-files/input/ml-dataset";
  String pathToCsvFile = "/var/hadoop/examples-files/input/ml-node-gen";
  
  SampleRecommender sampleRecommender = new SampleRecommender(pathToCsvFile);
  
  for(int i=1;i<=10;i++){
   List recommendationsList = sampleRecommender.getRecommendations(i,2);
   
   for (RecommendedItem recommendation : recommendationsList) {
    System.out.println(
      "User:" + i + 
      ", recommended item: " + recommendation.getItemID() + 
      " (value: " + recommendation.getValue() + ")");
   } 
  }
 }
 
 static class SampleRecommender {
  private DataModel model = null;
  private UserBasedRecommender recommender = null;
  
  public SampleRecommender(String path) throws IOException, TasteException
  {
   model = new FileDataModel(new File(path));
   UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
   UserNeighborhood neighborhood = new ThresholdUserNeighborhood(0.1, similarity, model);
   recommender = new GenericUserBasedRecommender(model, neighborhood, similarity);
  }
  
  public List getRecommendations(int user, int itemNumber) throws TasteException
  {
   if(this.model!=null && this.recommender!=null)
    return recommender.recommend(user, itemNumber);
   else
    return null;
  }
 }
}

Si nos fijamos un poco, podemos ver claramente que el "core" del recomendador se encuentra dentro del constructor llamado SampleRecommender. Tiene 4 lineas:

  1. Primero cargamos el dataset y creamos el modelo del mismo
  2. Le indicamos a Mahout qué algoritmo queremos usar para hacer comparaciones de las interacciones que tienen los usuarios con los distintos productos. El método que usamos aquí es el de coeficiente de correlación de Pearson con el cual le indicaremos el umbral de correlación que queremos utilizar. Mirando el link de wikipedia podemos ver que:
    1. Si r = 1, existe una correlación positiva perfecta. 
    2. Si 0 < r < 1, existe una correlación positiva.
    3. Si r = 0, no existe relación lineal pero podría ser no lineal
  3. Vamos a usar un umbral de correlación de 0.1 de tal manera que con que la correlación se levemente positiva, consideraremos que el producto se puede recomendar
  4. Por último, pasamos todos las variables previamente generadas para recoger nuestro generador.
Cuando ya tenemos el generador, lo único que tenemos que hacer es preguntarle sobre el usuario del que queramos sacar una recomendación y cuantas recomendaciones queremos obtener con el método recommender.recommend(user, itemNumber);

El resultado que podríais obtener es como el siguiente:

User:4, recommended item: 2 (value: 14.750008)
User:5, recommended item: 2 (value: 12.130403)
User:7, recommended item: 4 (value: 17.72526)
User:8, recommended item: 3 (value: 11.70087)
User:9, recommended item: 4 (value: 15.584593)
User:9, recommended item: 1 (value: 13.836835)

Los resultados obtenidos, al haber usado un dataset generado aleatoriamente, serán distintos cada vez que generemos un dataset nuevo. Además, dada la aleatoriedad del "algoritmo" de generación de datasets, es incluso posible que los resultados no guarden la relación necesaria para poder usarlos con el recomendador pero, con un par de intentos debería generar un dataset válido.

En el siguiente tutorial sobre Mahout, vamos a distribuir el recomendador en el cluster de Hadoop.

0 comentarios:

Publicar un comentario