machine-learning
Una introducción a la clasificación: Generando varios modelos usando Weka
Buscar..
Introducción
Este tutorial le mostrará cómo usar Weka en el código JAVA, cargar archivos de datos, entrenar clasificadores y explica algunos de los conceptos importantes detrás del aprendizaje automático.
Weka es un conjunto de herramientas para el aprendizaje automático. Incluye una biblioteca de técnicas de aprendizaje automático y visualización y presenta una GUI fácil de usar.
Este tutorial incluye ejemplos escritos en JAVA e incluye imágenes generadas con la GUI. Sugiero usar la GUI para examinar los datos y el código JAVA para experimentos estructurados.
Comenzando: Cargando un conjunto de datos desde el archivo
El conjunto de datos de la flor del iris es un conjunto de datos ampliamente utilizado para fines de demostración. Lo cargaremos, lo inspeccionaremos y lo modificaremos ligeramente para su uso posterior.
import java.io.File;
import java.net.URL;
import weka.core.Instances;
import weka.core.converters.ArffSaver;
import weka.core.converters.CSVLoader;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.RenameAttribute;
import weka.classifiers.evaluation.Evaluation;
import weka.classifiers.rules.ZeroR;
import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.lazy.IBk;
import weka.classifiers.trees.J48;
import weka.classifiers.meta.AdaBoostM1;
public class IrisExperiments {
public static void main(String args[]) throws Exception
{
//First we open stream to a data set as provided on http://archive.ics.uci.edu
CSVLoader loader = new CSVLoader();
loader.setSource(new URL("http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data").openStream());
Instances data = loader.getDataSet();
//This file has 149 examples with 5 attributes
//In order:
// sepal length in cm
// sepal width in cm
// petal length in cm
// petal width in cm
// class ( Iris Setosa , Iris Versicolour, Iris Virginica)
//Let's briefly inspect the data
System.out.println("This file has " + data.numInstances()+" examples.");
System.out.println("The first example looks like this: ");
for(int i = 0; i < data.instance(0).numAttributes();i++ ){
System.out.println(data.instance(0).attribute(i));
}
// NOTE that the last attribute is Nominal
// It is convention to have a nominal variable at the last index as target variable
// Let's tidy up the data a little bit
// Nothing too serious just to show how we can manipulate the data with filters
RenameAttribute renamer = new RenameAttribute();
renamer.setOptions(weka.core.Utils.splitOptions("-R last -replace Iris-type"));
renamer.setInputFormat(data);
data = Filter.useFilter(data, renamer);
System.out.println("We changed the name of the target class.");
System.out.println("And now it looks like this:");
System.out.println(data.instance(0).attribute(4));
//Now we do this for all the attributes
renamer.setOptions(weka.core.Utils.splitOptions("-R 1 -replace sepal-length"));
renamer.setInputFormat(data);
data = Filter.useFilter(data, renamer);
renamer.setOptions(weka.core.Utils.splitOptions("-R 2 -replace sepal-width"));
renamer.setInputFormat(data);
data = Filter.useFilter(data, renamer);
renamer.setOptions(weka.core.Utils.splitOptions("-R 3 -replace petal-length"));
renamer.setInputFormat(data);
data = Filter.useFilter(data, renamer);
renamer.setOptions(weka.core.Utils.splitOptions("-R 4 -replace petal-width"));
renamer.setInputFormat(data);
data = Filter.useFilter(data, renamer);
//Lastly we save our newly created file to disk
ArffSaver saver = new ArffSaver();
saver.setInstances(data);
saver.setFile(new File("IrisSet.arff"));
saver.writeBatch();
}
}
Entrene al primer clasificador: establecer una línea de base con ZeroR
ZeroR es un clasificador simple. No opera por instancia, sino que opera en la distribución general de las clases. Selecciona la clase con la mayor probabilidad a priori. No es un buen clasificador en el sentido de que no utiliza ninguna información en el candidato, pero a menudo se utiliza como una línea de base. Nota: Se pueden usar otras líneas de base como, por ejemplo: clasificadores estándar de la industria o reglas artesanales
// First we tell our data that it's class is hidden in the last attribute
data.setClassIndex(data.numAttributes() -1);
// Then we split the data in to two sets
// randomize first because we don't want unequal distributions
data.randomize(new java.util.Random(0));
Instances testset = new Instances(data, 0, 50);
Instances trainset = new Instances(data, 50, 99);
// Now we build a classifier
// Train it with the trainset
ZeroR classifier1 = new ZeroR();
classifier1.buildClassifier(trainset);
// Next we test it against the testset
Evaluation Test = new Evaluation(trainset);
Test.evaluateModel(classifier1, testset);
System.out.println(Test.toSummaryString());
La clase más grande en el conjunto te da una tasa correcta del 34%. (50 de 149)
Nota: El ZeroR realiza alrededor del 30%. Esto se debe a que nos dividimos aleatoriamente en un conjunto de pruebas y trenes. El conjunto más grande en el conjunto de trenes, por lo tanto, será el más pequeño en el conjunto de prueba. Hacer un buen set de prueba / tren puede valer la pena
Tener una idea de los datos. Entrenamiento Naive Bayes y kNN
Para construir un buen clasificador, a menudo necesitaremos tener una idea de cómo se estructuran los datos en el espacio de características. Weka ofrece un módulo de visualización que puede ayudar.
Algunas dimensiones ya separan bastante bien las clases. El ancho de los pétalos ordena el concepto con bastante claridad, en comparación con el ancho de los pétalos, por ejemplo.
La capacitación de clasificadores simples también puede revelar bastante sobre la estructura de los datos. Por lo general, me gusta usar Nearest Neighbor y Naive Bayes para ese propósito. Naive Bayes asume independencia, su buen desempeño es una indicación de que las dimensiones en sí mismas contienen información. k-Nearest-Neighbor funciona asignando la clase de las k instancias más cercanas (conocidas) en el espacio de características. A menudo se usa para examinar la dependencia geográfica local, lo usaremos para examinar si nuestro concepto está definido localmente en el espacio de características.
//Now we build a Naive Bayes classifier
NaiveBayes classifier2 = new NaiveBayes();
classifier2.buildClassifier(trainset);
// Next we test it against the testset
Test = new Evaluation(trainset);
Test.evaluateModel(classifier2, testset);
System.out.println(Test.toSummaryString());
//Now we build a kNN classifier
IBk classifier3 = new IBk();
// We tell the classifier to use the first nearest neighbor as example
classifier3.setOptions(weka.core.Utils.splitOptions("-K 1"));
classifier3.buildClassifier(trainset);
// Next we test it against the testset
Test = new Evaluation(trainset);
Test.evaluateModel(classifier3, testset);
System.out.println(Test.toSummaryString());
Naive Bayes se desempeña mucho mejor que nuestra línea de base recién establecida, indicando que las características independientes contienen información (¿recuerda el ancho de los pétalos?).
1NN también tiene un buen desempeño (de hecho, un poco mejor en este caso), lo que indica que parte de nuestra información es local. El mejor rendimiento podría indicar que algunos efectos de segundo orden también contienen información (si x e y que clase z) .
Juntándolo: entrenando un árbol
Los árboles pueden construir modelos que funcionan en características independientes y en efectos de segundo orden. Así que podrían ser buenos candidatos para este dominio. Los árboles son reglas que están juntas, una regla divide las instancias que llegan a una regla en subgrupos, que pasan a las reglas según la regla.
Los Tree Learners generan reglas, los encadenan y dejan de construir árboles cuando sienten que las reglas se vuelven demasiado específicas para evitar el sobreajuste. El ajuste excesivo significa construir un modelo que es demasiado complejo para el concepto que estamos buscando. Los modelos sobre ajustados tienen un buen desempeño en los datos del tren, pero mal en los nuevos datos
Utilizamos J48, una implementación JAVA de C4.5, un algoritmo popular.
//We train a tree using J48
//J48 is a JAVA implementation of the C4.5 algorithm
J48 classifier4 = new J48();
//We set it's confidence level to 0.1
//The confidence level tell J48 how specific a rule can be before it gets pruned
classifier4.setOptions(weka.core.Utils.splitOptions("-C 0.1"));
classifier4.buildClassifier(trainset);
// Next we test it against the testset
Test = new Evaluation(trainset);
Test.evaluateModel(classifier4, testset);
System.out.println(Test.toSummaryString());
System.out.print(classifier4.toString());
//We set it's confidence level to 0.5
//Allowing the tree to maintain more complex rules
classifier4.setOptions(weka.core.Utils.splitOptions("-C 0.5"));
classifier4.buildClassifier(trainset);
// Next we test it against the testset
Test = new Evaluation(trainset);
Test.evaluateModel(classifier4, testset);
System.out.println(Test.toSummaryString());
System.out.print(classifier4.toString());
El aprendiz de árbol entrenado con la mayor confianza genera las reglas más específicas y tiene el mejor rendimiento en el conjunto de pruebas; al parecer, la especificidad está justificada.
Nota: ambos alumnos comienzan con una regla sobre el ancho de los pétalos. ¿Recuerdas cómo notamos esta dimensión en la visualización?