Поиск…


Вступление

В этом уроке вы узнаете, как использовать Weka в коде JAVA, загружать файлы данных, классифицировать поезда и объяснять некоторые важные концепции машинного обучения.

Weka - инструментарий для машинного обучения. Он включает в себя библиотеку методов машинного обучения и визуализации и предлагает удобный графический интерфейс.

Этот учебник включает примеры, написанные в JAVA, и включает в себя визуальные эффекты, созданные с помощью графического интерфейса. Я предлагаю использовать графический интерфейс для изучения данных и кода JAVA для структурированных экспериментов.

Начало работы: загрузка набора данных из файла

Набор данных Iris flower - широко используемый набор данных для демонстрационных целей. Мы загрузим его, осмотрим и слегка изменим для последующего использования.

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();
  }
}

Обучить первый классификатор: установка базовой линии с помощью ZeroR

ZeroR - простой классификатор. Он не работает на один экземпляр, а работает на общем распределении классов. Он выбирает класс с наибольшей априорной вероятностью. Это не хороший классификатор в том смысле, что он не использует никакой информации в кандидате, но часто используется в качестве базовой линии. Примечание: можно использовать другие базовые линии: например, отраслевые стандартные классификаторы или ручные правила

 // 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());

Самый большой класс в наборе дает вам правильную ставку на 34%. (50 из 149)

Фактическое распределение классов в множестве

Примечание. ZeroR выполняет около 30%. Это происходит потому, что мы беспорядочно разбились на поезд и тестовый набор. Самый большой набор в наборе поездов, таким образом, будет самым маленьким в тестовом наборе. Создание хорошего набора тестов / поездов может стоить вашего времени

Получение информации о данных. Обучение Наивный Байес и кНН

Чтобы построить хороший классификатор, нам часто нужно понять, как данные структурированы в пространстве объектов. Weka предлагает модуль визуализации, который может помочь.

графики 2-х размеров, классы окрашены в

Некоторые измерения уже отлично отделяют классы. Петля-ширина заказывает концепцию довольно аккуратно, например, по сравнению с шириной лепестков.

Тренировка простых классификаторов может также выявить некоторые особенности структуры данных. Для этой цели я обычно предпочитаю использовать Nearest Neighbor и Naive Bayes. Наивный Байес принимает независимость, он хорошо работает, это указание на то, что размеры сами по себе содержат информацию. k-Nearest-Neighbor работает, назначая класс k ближайших (известных) экземпляров в пространстве объектов. Он часто используется для изучения локальной географической зависимости, мы будем использовать его для проверки того, определена ли наша концепция локально в пространстве объектов.

 //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());

Наивный Байес работает намного лучше, чем наша недавно установленная базовая линия, указав, что независимые функции содержат информацию (помните ширину лепестка?).

1NN тоже хорошо работает (на самом деле немного лучше в этом случае), что указывает на то, что часть нашей информации является локальной. Более высокая производительность может указывать на то, что некоторые эффекты второго порядка также содержат информацию (если x и y, чем класс z) .

Объединение: Обучение дереву

Деревья могут создавать модели, которые работают над независимыми функциями и эффектами второго порядка. Таким образом, они могут быть хорошими кандидатами для этого домена. Деревья - это правила, которые объединены вместе, правило разбивает экземпляры, которые приходят к правилу в подгруппах, которые переходят к правилам правила.

Деревенщицы генерируют правила, объединяют их вместе и прекращают строить деревья, когда они чувствуют, что правила становятся слишком специфичными, чтобы избежать переобучения. Overfitting означает создание модели, которая слишком сложна для концепции, которую мы ищем. Сверхмощные модели хорошо работают на данных поезда, но плохо на новых данных

Мы используем J48, JAVA-реализацию C4.5 - популярный алгоритм.

//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());

Ученик, обучаемый с наивысшим доверием, генерирует наиболее конкретные правила и обладает наилучшей производительностью на тестовом наборе, по всей видимости, определенность является гарантией.

введите описание изображения здесь введите описание изображения здесь

Примечание. Оба ученика начинают с правила по ширине лепестков. Помните, как мы заметили это измерение в визуализации?



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow