Get it on Google Play

Machine Learning con Java y Weka

13-08-2016
 
Weka Logo

Weka Logo

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.

Leave a Reply

© Albert Coronado Calzada