Weka es una librería Java con una colección de algoritmos(Pre-procesado, clasificación, regresión, clustering, etc.) para Machine Learning(ML). Además, podemos usar Weka con Big Data.
Una potente herramienta para desarrolladores que quieran incorporar Machine Learning en sus aplicaciones. En el articulo de hoy vamos a ver como crear un modelo de predicción con esta herramienta.
Crear el proyecto con Gradle
En mi caso ya soy fan de Gradle, entonces voy a usar esta herramienta crear el proyecto. El fichero ‘build.gradle’ con la dependencia de Weka queda de la siguiente forma:
apply plugin:'application' mainClassName = "com.lostsys.docker.Main" repositories { mavenCentral() } dependencies { compile 'org.slf4j:slf4j-api:1.7.12' compile 'com.github.docker-java:docker-java:3.0.1' testCompile 'junit:junit:4.12' }
El fichero con los datos de entrenamiento
Gradle nos permite incorporar los datos de diferentes fuentes como la base de datos. En este caso haremos que coja los datos de configuración de un fichero de texto ‘datos.txt’:
@relation weather @attribute outlook {sunny, overcast, rainy} @attribute temperature numeric @attribute humidity numeric @attribute windy {TRUE, FALSE} @attribute play {yes, no} @data sunny,85,85,FALSE,no sunny,80,90,TRUE,no overcast,83,86,FALSE,yes rainy,70,96,FALSE,yes rainy,68,80,FALSE,yes rainy,65,70,TRUE,no overcast,64,65,TRUE,yes sunny,72,95,FALSE,no sunny,69,70,FALSE,yes rainy,75,80,FALSE,yes sunny,75,70,TRUE,yes overcast,72,90,TRUE,yes overcast,81,75,FALSE,yes rainy,71,91,TRUE,no
En este fichero están los datos en si y la definición de la tipología de dato en cada columna. Es fácil de entender.
Classe Java
Y aquí nuestra classe Java para ver los resultados:
package com.lostsys.weka; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList; import weka.classifiers.Classifier; import weka.classifiers.Evaluation; import weka.classifiers.evaluation.Prediction; import weka.classifiers.rules.DecisionTable; import weka.classifiers.rules.PART; import weka.classifiers.trees.DecisionStump; import weka.classifiers.trees.J48; import weka.core.Instances; public class Main { static public void main(String[] args) { try { /* Cargamos el fichero con los datos */ BufferedReader datafile = new BufferedReader(new FileReader("datos.txt")); Instances data = new Instances(datafile); /* Seleccionamos la columna de los datos a estimar */ data.setClassIndex(data.numAttributes() - 1); /* Creamos dos grupos uno de entreno y otro de test */ int numFolds=14; Instances[] trainingSplits=new Instances[numFolds]; Instances[] testingSplits= new Instances[numFolds]; for (int i = 0; i < numFolds; i++) { trainingSplits[i] = data.trainCV(numFolds, i); testingSplits[i] = data.testCV(numFolds, i); } /* Ejecutamos cada diferentes modelos */ ejecutarModelo( new J48(), trainingSplits, testingSplits); // a decision tree ejecutarModelo( new PART(), trainingSplits, testingSplits); ejecutarModelo( new DecisionTable(), trainingSplits, testingSplits);//decision table majority classifier ejecutarModelo( new DecisionStump(), trainingSplits, testingSplits); //one-level decision tree } catch (Exception ex) { ex.printStackTrace(); } } static public void ejecutarModelo(Classifier model, Instances[] trainingSplits, Instances[] testingSplits) throws Exception { ArrayList<Prediction> predictions = new ArrayList<Prediction>(); /* Entrenamos el modelo */ for (int i = 0; i < trainingSplits.length; i++) { model.buildClassifier(trainingSplits[i]); } /* Testenamos el modelo */ for (int i = 0; i < testingSplits.length; i++) { Evaluation evaluation = new Evaluation(testingSplits[i]); evaluation.evaluateModel(model, testingSplits[i]); predictions.addAll( evaluation.predictions() ); } /* Calculamos la exactitud del modelo */ double accuracy = calculateAccuracy(predictions); System.out.println("Exactitud del modelo " + model.getClass().getSimpleName() + ": " + String.format("%.2f%%", accuracy)); } public static double calculateAccuracy(ArrayList<Prediction> predictions) { double correct = 0; for (Prediction np:predictions) { if (np.predicted() == np.actual()) correct++; } return 100 * correct / predictions.size(); } }
Conclusiones
Weka es una librería brutal para trabajar con Machine Learning. Te olvidas de los distintos algoritmos(Que son bastante difíciles de implementar, por cierto) para centrarte en lo verdaderamente importante(La aplicación).
Además también dispone de una interfaz gráfica muy potente, que no he probado. En mi caso, me interesaban solo los algoritmos.