Una vez que ya conocemos los conceptos y componentes principales de Hadoop según vimos en los posts anteriores:
Continuaremos probando más funcionalidad de y para Hadoop on Azure. En esta ocasíón Mahout.
“La verdad es que cuando la semana pasada me disponía a indagar sobre el tema de mahout, no me imaginaba que la Intenligencia Artifical estuviera tan cerca, durante la carrera pensaba que este tipo de algoritmos sólo eran teoría y estarían lejos de acercarse a una realidad, pero sinceramente, creo que me equivoqué”
¿Que es Mahout?
Mahout proviene del Hindi, mahaut, “montador de elefantes”, de ahí el logotipo. La labor de un Mahout es permanecer desde joven vinculado a un elefante también joven a fin de que tanto jinete como elefante se conozcan mutuamente a lo largo de toda la vida. ¡Se podría sacar de aquí una peli, seguro,jeje…! Técnicamente hablando, Apache Mahout,es una máquina de aprendizaje cuyo objetivo consiste en construir bibliotecas escalables de aprendizaje automático.
Los sistemas de recomendación son alguna de las aplicaciones de aprendizaje más conocida hoy día. Su objetivo es tratar de presentar al usuario items de información: películas, música, libros, noticias, páginas web, etc, sobre las que el usuario está interesado. Todo ello basado en su comportamiento previo. Estos algoritmos proporcionan una funcionalidad importante para muchos sitios de redes sociales , compras on-line, streaming, y otros sitios de Internet. Mahout ofrece un motor de recomendación out-of-the-box que es fácil de usar, tiene muchas características útiles, y es escalable en Hadoop. Algunas de las aplicaciones más conocidas que utilizan estos algoritmos, son Pandora Radio o Netflix o incluso la propia web de Amazon que ofrece/recomienda a sus clientes productos a partir de los ya comprados por otros.
A continuación veremos las técnicas que A continuación veremos las técnicas que por ahora nos ofrece Hadoop On Azure, es decir, Clasificación y Agrupación (Clustering).
1) Clasificación
Partamos del propio ejemplo que nos presenta Hadoop o directamente desde aquí. Este ejemplo esta basado 100% en el ejemplo del website de Mahout el cual consiste en:
“The 20 Newsgroups data set is a collection of approximately 20,000 newsgroup documents, partitioned (nearly) evenly across 20 different newsgroups. The 20 newsgroups collection has become a popular data set for experiments in text applications of machine learning techniques, such as text classification and text clustering. We will use Mahout Bayes Classifier to create a model that would classify a new document into one of the 20 newsgroup.”
Para ello tal y como nos dice el tutorial y desde el Head Node al que accedemos remotamente:
1) Descargamos del fichero de datos en la ruta ““C:appsdistmahout-0.5examplesbinwork”
2) Descomprimimos el fichero “.tar.gz” en la capeta: “C:appsdistmahout-0.5examplesbinwork20news-bydate”
3) Ejecutamos el “.cmd” c:appsdistmahout-0.5examplesbinbuild-20news-bayes.cmd”
Nota: Aunque esperamos que funcione, resulta que no es así, parece que se trata de algún error de configuración en los scripts de “Mahout” para Azure on Hadoop o, incluso de alguna incompatibilidad de versiones entre los comandos Mahout y Hadoop.
Para solucionar el problema modificamos el script “build-20news-bayes.cmd” sustituyendo la llamada al comando Mahout por la llamada directa a hadoop (realmente es lo que hace internamente el comando Mahout), es decir,
Sustituimos esto:
call mahout.cmd org.apache.mahout.classifier.bayes.preparetwentynewsgroups ^
-p %work_path%20news-bydate-train ^
-o %work_path%bayes-train-input ^
-a org.apache.mahout.vectorizer.defaultanalyzer ^
-c utf-8call mahout.cmd org.apache.mahout.classifier.bayes.preparetwentynewsgroups ^
-p %work_path%20news-bydate-test ^
-o %work_path%bayes-test-input ^
-a org.apache.mahout.vectorizer.defaultanalyzer ^
-c utf-8
por esto otro:
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar ^
org.apache.mahout.driver.MahoutDriver ^
org.apache.mahout.classifier.bayes.PrepareTwentyNewsgroups ^
-p %WORK_PATH%20news-bydate-train ^
-o %WORK_PATH%bayes-train-input ^
-a org.apache.mahout.vectorizer.DefaultAnalyzer ^
-c UTF-8call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar ^
org.apache.mahout.driver.MahoutDriver ^
org.apache.mahout.classifier.bayes.PrepareTwentyNewsgroups ^
-p %WORK_PATH%20news-bydate-test ^
-o %WORK_PATH%bayes-test-input ^
-a org.apache.mahout.vectorizer.DefaultAnalyzer ^
-c UTF-8
De todas formas, os dejo el contenido completo del fichero “build-20news-bayes.cmd” con el problema solucionado.
@echo off
@rem
@rem Licensed to the Apache Software Foundation (ASF) under one or more
@rem contributor license agreements. See the NOTICE file distributed with
@rem this work for additional information regarding copyright ownership.
@rem The ASF licenses this file to You under the Apache License, Version 2.0
@rem (the "License"); you may not use this file except in compliance with
@rem the License. You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem
@rem Downloads the 20newsgroups dataset, trains and tests a bayes classifier.
@rem
@rem To run: change into the mahout directory and type:
@rem examples/bin/build-20news.sh
setlocal enabledelayedexpansion
set SCRIPT_PATH=%~dp0
set MAHOUT_BIN_PATH=%SCRIPT_PATH%....bin
set WORK_PATH=%SCRIPT_PATH%work20news-bydate
set HDFS_WORK_PATH=examples/bin/work/20news-bydate/
if not exist %WORK_PATH% (
mkdir %WORK_PATH%
)
if not exist %WORK_PATH%20news-bydate-train (
goto :ErrorMessage
)
if not exist %WORK_PATH%20news-bydate-test (
goto :ErrorMessage
)
pushd %MAHOUT_BIN_PATH%
REM call mahout.cmd org.apache.mahout.classifier.bayes.PrepareTwentyNewsgroups ^
REM -p %WORK_PATH%20news-bydate-train ^
REM -o %WORK_PATH%bayes-train-input ^
REM -a org.apache.mahout.vectorizer.DefaultAnalyzer ^
REM -c UTF-8
REM call mahout.cmd org.apache.mahout.classifier.bayes.PrepareTwentyNewsgroups ^
REM -p %WORK_PATH%20news-bydate-test ^
REM -o %WORK_PATH%bayes-test-input ^
REM -a org.apache.mahout.vectorizer.DefaultAnalyzer ^
REM -c UTF-8
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar ^
org.apache.mahout.driver.MahoutDriver ^
org.apache.mahout.classifier.bayes.PrepareTwentyNewsgroups ^
-p %WORK_PATH%20news-bydate-train ^
-o %WORK_PATH%bayes-train-input ^
-a org.apache.mahout.vectorizer.DefaultAnalyzer ^
-c UTF-8
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar ^
org.apache.mahout.driver.MahoutDriver ^
org.apache.mahout.classifier.bayes.PrepareTwentyNewsgroups ^
-p %WORK_PATH%20news-bydate-test ^
-o %WORK_PATH%bayes-test-input ^
-a org.apache.mahout.vectorizer.DefaultAnalyzer ^
-c UTF-8
@rem mapreduce test method used on hadoop
set TEST_METHOD="mapreduce"
call hadoop.cmd dfs -rmr ^
%HDFS_WORK_PATH%bayes-train-input
call hadoop.cmd dfs -rmr ^
%HDFS_WORK_PATH%bayes-test-input
call hadoop.cmd dfs -put ^
%WORK_PATH%bayes-train-input ^
%HDFS_WORK_PATH%bayes-train-input
call hadoop.cmd dfs -put ^
%WORK_PATH%bayes-test-input ^
%HDFS_WORK_PATH%bayes-test-input
REM call mahout.cmd trainclassifier ^
REM -i %HDFS_WORK_PATH%bayes-train-input ^
REM -o %HDFS_WORK_PATH%bayes-model ^
REM -type bayes ^
REM -ng 1 ^
REM -source hdfs
REM call mahout.cmd testclassifier ^
REM -m %HDFS_WORK_PATH%bayes-model ^
REM -d %HDFS_WORK_PATH%bayes-test-input ^
REM -type bayes ^
REM -ng 1 ^
REM -source hdfs ^
REM -method %TEST_METHOD%
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar ^
org.apache.mahout.driver.MahoutDriver ^
trainclassifier ^
-i %HDFS_WORK_PATH%bayes-train-input ^
-o %HDFS_WORK_PATH%bayes-model ^
-type bayes ^
-ng 1 ^
-source hdfs
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar ^
org.apache.mahout.driver.MahoutDriver ^
testclassifier ^
-m %HDFS_WORK_PATH%bayes-model ^
-d %HDFS_WORK_PATH%bayes-test-input ^
-type bayes ^
-ng 1 ^
-source hdfs ^
-method %TEST_METHOD%
popd
goto :eof
:ErrorMessage
echo Please download 20news-bydate.tar.gz from:
echo http://people.csail.mit.edu/jrennie/20Newsgroups/20news-bydate.tar.gz
echo and extract it under:
echo %WORK_PATH%
4) Solucionado el problema ahora si, el resultado esperado es la siguiente “Confusion Matrix”. Esta misma matriz puede verse en el ejemplo de partida de Apache Mohout que indicábamos antes.
En este ejemplo, puede verse como funciona una “Confusion Matrix” y un poco de teoría.
Adicionalmente, aquí tenemos otro ejemplo de clasificación (en este caso más concretamente, un ejemplo de algoritmo de recomendación).
2) Agrupación(Clustering)
Partimos nuevamente del propio ejemplo que nos presenta Hadoop o directamente desde aquí. Este ejemplo esta basado 100% en el ejemplo del website de Mahout el cual consiste en:
“The example will demonstrate clustering of control charts which exhibits a time series. Control charts are tools used to determine whether or not a manufacturing or business process is in a state of statistical control. Such control charts are generated / simulated over equal time interval and available for use in UCI machine learning database. The data is described here .”
Para ello y como nos dice el tutorial:
1) Descargamos el fichero “http://archive.ics.uci.edu/ml/databases/synthetic_control/synthetic_control.data” y lo situamos en la carpeta “C:appsdistmahout-0.5examplesbinworkclustering”
2) Ejecutamos “C:appsdistmahout-0.5examplesbinbuild-cluster-syntheticcontrol.cmd” y elegimos el tipo de “clustering”:
3) De la misma manera que para el ejemplo anterior, volvemos a tener problemas así que tenemos que hacer algunos ajustes:
Sustituyendo esto:
call mahout hadoop fs -rmr %HDFS_WORK_PATH%
call mahout hadoop fs -mkdir %HDFS_WORK_PATH%
call mahout hadoop fs -put %WORK_PATH%synthetic_control.data %HDFS_WORK_PATH%
call mahout org.apache.mahout.clustering.syntheticcontrol.%_clustertype%.Job
Por esto otro:
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar org.apache.mahout.driver.MahoutDriver ^
hadoop fs -rmr %HDFS_WORK_PATH%
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar org.apache.mahout.driver.MahoutDriver ^
hadoop fs -mkdir %HDFS_WORK_PATH%
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar org.apache.mahout.driver.MahoutDriver ^
hadoop fs -put %WORK_PATH%synthetic_control.data %HDFS_WORK_PATH%
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar org.apache.mahout.driver.MahoutDriver ^
org.apache.mahout.clustering.syntheticcontrol.%_clustertype%.Job
Nuevamente, aquí dejo el fichero “build-cluster-syntheticcontrol.cmd” con el problema ya solucionado.
@echo off
@rem
@rem Licensed to the Apache Software Foundation (ASF) under one or more
@rem contributor license agreements. See the NOTICE file distributed with
@rem this work for additional information regarding copyright ownership.
@rem The ASF licenses this file to You under the Apache License, Version 2.0
@rem (the "License"); you may not use this file except in compliance with
@rem the License. You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem
@rem Downloads the Synthetic control dataset and prepares it for clustering
@rem
@rem To run: change into the mahout directory and type:
@rem examples/bin/cluster-syntheticcontrol.sh
setlocal enabledelayedexpansion
set SCRIPT_PATH=%~dp0
set MAHOUT_BIN_PATH=%SCRIPT_PATH%....bin
set WORK_PATH=%SCRIPT_PATH%workclustering
set HDFS_WORK_PATH=testdata
if not exist %WORK_PATH% (
mkdir %WORK_PATH%
)
if not exist %WORK_PATH%synthetic_control.data (
echo Please downloading Synthetic control data from:
echo http://archive.ics.uci.edu/ml/databases/synthetic_control/synthetic_control.data
echo and put it under:
echo %WORK_PATH%synthetic_control.data
goto :end
)
:main
echo "Please select a number to choose the corresponding clustering algorithm"
echo "1. canopy clustering"
echo "2. kmeans clustering"
echo "3. fuzzykmeans clustering"
echo "4. dirichlet clustering"
echo "5. meanshift clustering"
set /p _choice="Enter your choice:"
@rem set _algorithms=canopy kmeans fuzzykmeans dirichlet meanshift
if [%_choice%] == [1] (
set _clustertype=canopy
) else (
if [%_choice%] == [2] (
set _clustertype=kmeans
) else (
if [%_choice%] == [3] (
set _clustertype=fuzzykmeans
) else (
if [%_choice%] == [4] (
set _clustertype=dirichlet
) else (
if [%_choice%] == [5] (
set _clustertype=meanshift
) else (
echo "Invalid choice %_choice%. Please try again"
goto :end
)))))
echo "ok. You chose %_choice% and we'll use %_clustertype% Clustering"
pushd %MAHOUT_BIN_PATH%
echo "DFS is healthy... "
echo "Uploading Synthetic control data to HDFS"
@REM call mahout hadoop fs -rmr %HDFS_WORK_PATH%
@REM call mahout hadoop fs -mkdir %HDFS_WORK_PATH%
@REM call mahout hadoop fs -put %WORK_PATH%synthetic_control.data %HDFS_WORK_PATH%
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar org.apache.mahout.driver.MahoutDriver ^
hadoop fs -rmr %HDFS_WORK_PATH%
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar org.apache.mahout.driver.MahoutDriver ^
hadoop fs -mkdir %HDFS_WORK_PATH%
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar org.apache.mahout.driver.MahoutDriver ^
hadoop fs -put %WORK_PATH%synthetic_control.data %HDFS_WORK_PATH%
echo "Successfully Uploaded Synthetic control data to HDFS "
@REM call mahout org.apache.mahout.clustering.syntheticcontrol.%_clustertype%.Job
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar org.apache.mahout.driver.MahoutDriver ^
org.apache.mahout.clustering.syntheticcontrol.%_clustertype%.Job
:end
popd
4) Una vez que hemos lanzado este script, ejecutamos los dos siguientes para la comprobación y obtención de resultados:
Para verificar que el resultado se encuentra en HDFS, ejecutamos:
- “hadoop fs -lsr output”, o,
- “#ls output”, desde la consola interactiva de Java Script.
Para descargar el resultado desde HDFS en un directorio local del Head Node del cluster de Hadoop:
- “hadoop fs -get output C:appsdistmahout-0.5examplesbinworkclustering”
- Veremos que la ruta “C:Appsdistmahout-0.5examplesbinworkclustering” contiene la carpeta “output” como resultado del comando anterior.
5) A continuación, analizaremos los datos obtenidos utilizando el parámetro de Mahout “clusterdump”.
- Creamos un nuevo script:
@echo off
setlocal enabledelayedexpansion
set SCRIPT_PATH=%~dp0
set MAHOUT_BIN_PATH=%SCRIPT_PATH%....bin
set MAHOUT_HOME=%MAHOUT_BIN_PATH%..
pushd %MAHOUT_BIN_PATH%
call %HADOOP_HOME%binhadoop jar %MAHOUT_BIN_PATH%..mahout-examples-0.5-job.jar ^
org.apache.mahout.driver.MahoutDriver ^
clusterdump ^
--seqFileDir output/clusters-0 ^
--pointsDir output/clusteredPoints ^
--output clusteranalyze.txt
popd
Nota: En vista de que el resultado esperado para este ejemplo no es satisfactorio, puesto que no obtendremos resultados, en este enlace podemos ver un análisis de los resultados de manera genérica así como el contenido del fichero de salida, “clusteranalyze.txt”. Este fichero lo encontraremos en la carpeta “C:appsdistmahout-0.5bin” una vez hayamos ejecutado este último script.
Adicionalmente, de las 5 opciones que presenta este último ejemplo sólo la primera y las dos últimas funcionan, el resto producen errores y como ya hemos comentado, es posible que sea debido a las incompatibilidades para las versiones actuales entre Hadoop y Mahout. Siempre que ocurran estos problemas podemos intentar solucionarlo descargando y actualizando sus nuevas versiones: Hadoop y Mahout.
Importante: Si optamos por actualizar las versiones, tengamos en cuenta lo siguiente:
- Es posible que las nuevas versiones no contengan los mismo ejemplos.
- Los script (.cmd) adaptados a Windows, tendremos que generarlos manualmente a partir de los “.sh” de Linux/unix que se distribuyen con la versión original de apache. Por ejemplo, para mahout descargaremos la nueva versión, mahot-distribution-0.7, y la renombraremos por “mahout-0.7” ubicándola en “C:appsdist” al mismo nivel que “mahout-0.5”, así podremos intentar reutilizar los script (.cmd) de la versión anteriores.
- A partir de aquí, toca probar y cruzar los dedos, por eso, no recomiendo esto a menos que los cambios a realizar fueran mínimos. Esperemos a que Microsft vaya realizando y adaptando las versiones adecuadamente.
Aunque estos algoritmos y ejemplos están cambiando constantemente y Hadoop aun está en “Preview”, espero haber aclarado incógnitas sobre este nuevo mundo de la Inteligencia Artificial con Mahout… !
Saludos y feliz “cacharreo” con Mahout…
Juanlu,ElGuerre