Projekt z przedmiotu
Techniki Analizy Danych
Politechnika Łódzka
FTIiMS
Kierunek: Matematyka
Specjalność: Analiza Danych w Biznesie i Logistyce
Olga Grzywińska
Aleksandra Wilk
Łódź, styczeń 2014
Celem naszego projektu jest porównanie dwóch klasyfikatorów: naiwny klasyfikator
bayesowski i algorytm k-najbliższych sąsiadów.
W CZĘŚCI 1 wykorzystamy do tego środowisko Weka KnowledgeFlow.
W CZĘŚCI 2 wykorzystamy program NetBeanse i napiszemy kod w Javie odpowiadający
utworzonemu wcześniej schematowi.
CZĘŚĆ 1
W środowisku Weka KonowledgeFlow tworzymy projekt:
1. Wczytywanie danych
Z folderu DataSources wybieramy
ArffLoader
i umieszczamy go w przestrzeni
roboczej. Umożliwi on nam wczytanie danych z rozszerzeniem arff. Klikamy
prawym przyciskiem myszy na ikonę i wybieramy Configure. W polu Filename
wprowadzamy ścieżkę dostępu do danych. W naszym projekcie będziemy
pracować na danych
vote.arff
dostępnych w programie Weka. Na podstawie 16
różnych atrybutów, będziemy określać czy dana osoba jest demokratą czy
republikaninem.
Możemy obejrzeć graficzne przestawienie danych. Z folderu Visualization
wybieramy
DataVisualizer
. Następnie przesyłamy dataSet z ArffLoader do
DataVisualizer. W tym celu klikamy prawym przyciskiem na ArffLoader
wybieramy dataSet i klikamy na DataVisualizer.
2. Wybór atrybutu klasowego
Z folderu Visualization wybieramy
ClassAssigner
. Pozwala nam on na wybór
atrybutu klasowego. Klikamy prawym przyciskiem na ArffLoader, wybieramy
dataSet i łączymy z ClassAssigner. W opcjach domyślnie ustawiony jest atrybur
Class, dowolny atrubut można ustawić jako klasowy. My jednak zostaniemy przy
ustawieniu domyślnym.
3. Podział danych
Podzielimy teraz dane na zbiór treningowy i testowy. Zrobimy to na dwa
sposoby:
3-krotną kroswalidację, czyli oryginalna próba jest dzielona na
3 podzbiory. Następnie kolejno każdy z nich bierze się jako zbiór testowy,
a pozostałe razem jako zbiór uczący i wykonuje analizę. Analiza jest więc
wykonywana 3 razy. 3 rezultaty są następnie uśredniane w celu uzyskania
jednego wyniku.
Podział procentowy, czyli 2/3 danych bierze się jako zbiór uczący, a
pozostałe jako zbiór testowy.
Z folderu Evaluation wybieramy
CrossValidationFoldMaker
oraz
TrainTestSplitMaker
. Przesyłamy dataSet z CrossAssigner do każdego z nich.
W ustawieniach TrainTestSplitMaker w polu trainPercent wpisujemy jaki
procent danych ma być zbiorem uczącym, w naszym przypadku 66.0.
Aby zobaczyć w jaki sposób dane zostały podzielone za pomocą kroswalidacji
trzeba z folderu Visualization wybrać dwukrotnie
TextViewer
do jednego
przesłać trainingSet, a do drugiego testSet.
Podobnie w drugim przypadku.
4. Klasyfikacja
Sklasyfikujemy teraz dane za pomocą dwóch różnych algorytmów.
Wykorzystamy dwa rózne klasyfikatory:
Naiwny klasyfikator bayesowski- Zadaniem klasyfikatora Bayes’a jest
przyporządkowanie nowego przypadku do jednej z klas decyzyjnych, przy
czym zbiór klas decyzyjnych musi być skończony i zdefiniowany apriori.
Naiwny klasyfikator Bayes’a jest statystycznym klasyfikatorem, opartym
na twierdzeniu Bayesa.
Metoda k-najbliższych sąsiadów- W metodzie tej zaliczamy rozpoznawany
obiekt do tej klasy, do której należy większość z jego K najbliższych
sąsiadów.
Z folderu Classifiers wybieramy podfolder bayes, a następnie
NaiveBayes
oraz
z podfolderu lazy wybieramy
IBk
. Z CrossValidationFoldMaker przesyłamy
trainingSet i testSet do każdego z klasyfikatorów.
W ustawieniach IBk w polu KNN wpisujemy liczbę sąsiadów. W naszym
przypadku niech to będzie 3.
Podobnie w przypadku TrainTestSplitMaker.
5. Ocena klasyfikacji
Ocenimy teraz poprawność klasyfikacji. Dla każdego z klasyfikatorów, z folderu
Evaluation wybieramy
ClassifierPerrformanceEvaluator
i przesyłamy do
niego batchClasifier.
6. Wyświetlanie wyniku
Aby wyświetlić efekty klasyfikacji w formie tekstowej z folderu Visualization
musimy wybrać
TextViewer
i przesłać do niego text z
ClassifierPerrformanceEvaluator (dla przejrzystości użyjemy dwóch
TextViewer).
Aby wyświetlić efekty klasyfikacji w formie graficznej z folderu Visualization
musimy wybrać
ModelPerformanceChart
i przesłać do niego thresholdData z
ClassifierPerrformanceEvaluator (dla przejrzystości użyjemy dwóch
ModelPerformanceChart).
7.Podsumowanie
Aby uruchomić schemat wystarczy kliknąć strzałkę (Run this flow) w lewym
górnym rogu. Możemy teraz zobaczyć wyniki ewaluacji.
Klikając prawym przyciskiem myszy na TextViewer wybieramy Show results.
Wyświetlają nam się wyniki:
Dla CrossValidationFoldMaker
NaiveBayes
IBk
=== Evaluation result ===
Scheme: NaiveBayes
Relation: vote
Correctly Classified Instances 394
90.5747 %
Incorrectly Classified Instances 41
9.4253 %
Kappa statistic 0.8044
Mean absolute error 0.0979
Root mean squared error 0.2942
Relative absolute error 20.648 %
Root relative squared error 60.4328 %
Coverage of cases (0.95 level) 93.1034 %
Mean rel. region size (0.95 level) 53.3333 %
Total Number of Instances 435
=== Detailed Accuracy By Class ===
TP Rate FP Rate Precision Recall F-Measure ROC Area Class
0.895 0.077 0.948 0.895 0.921 0.971 democrat
0.923 0.105 0.847 0.923 0.883 0.971 republican
Avg. 0.906 0.088 0.909 0.906 0.906 0.971
=== Confusion Matrix ===
a b <-- classified as
239
28
| a = democrat
13
155
| b = republican
=== Evaluation result ===
Scheme: IBk
Options: -K 3 -W 0 -A "weka.core.neighboursearch.LinearNNSearch -A
\"weka.core.EuclideanDistance -R first-last\""
Relation: vote
Correctly Classified Instances 402
92.4138 %
Incorrectly Classified Instances 33
7.5862 %
Kappa statistic 0.8426
Mean absolute error 0.0825
Root mean squared error 0.2363
Relative absolute error 17.3873 %
Root relative squared error 48.5258 %
Coverage of cases (0.95 level) 97.7011 %
Mean rel. region size (0.95 level) 58.1609 %
Total Number of Instances 435
=== Detailed Accuracy By Class ===
TP Rate FP Rate Precision Recall F-Measure ROC Area Class
0.91 0.054 0.964 0.91 0.936 0.975 democrat
0.946 0.09 0.869 0.946 0.906 0.975 republican
Avg. 0.924 0.068 0.927 0.924 0.925 0.975
=== Confusion Matrix ===
a b <-- classified as
243
24
| a = democrat
9
159
| b = republican
Z podanych powyżej wyników możemy odczytać, że dla naiwnego klasyfikatora
bayesowskiego zostały poprawnie sklasyfikowane 394 instancje, to jest
90.5747% wszystkich danych. Bardziej szczegółowy wynik widzimy niżej w
Confusion Matrix. Wśród demokratów poprawnie sklasyfikowanych zostało 239
instancji a niepoprawnie 28, a wśród republikanów poprawnie 155 a błędnie 13.
Porównując te wyniki z wynikami dla algorytmu k-najbliższych sąsiadów, gdzie
poprawnie sklasyfikowanych zostało 92.4138 % instancji, łatwo zauważyć, że
większą poprawnością wykazuje sie algorytm IBk.
Możemy również obejrzeć graficzne przedstawienie powyższych wyników. W
tym celu musimy kliknać prawym przyciskiem myszy na
ModelPerformanceChart i wybrać Show chart. Wyświetla nam się:
Dla TrainTestSplitMaker
NaiveBayes
IBk
=== Evaluation result ===
Scheme: NaiveBayes
Relation: vote
Correctly Classified Instances 135
91.2162 %
Incorrectly Classified Instances 13
8.7838 %
Kappa statistic 0.8232
Mean absolute error 0.0912
Root mean squared error 0.2858
Relative absolute error 19.04 %
Root relative squared error 57.6557 %
Coverage of cases (0.95 level) 93.2432 %
Mean rel. region size (0.95 level) 53.0405 %
Total Number of Instances 148
=== Detailed Accuracy By Class ===
TP Rate FP Rate Precision Recall F-Measure ROC Area Class
0.872 0.032 0.974 0.872 0.92 0.98 democrat
0.968 0.128 0.845 0.968 0.902 0.98 republican
Avg. 0.912 0.072 0.92 0.912 0.913 0.98
=== Confusion Matrix ===
a b <-- classified as
75
11
| a = democrat
2
60
| b = republican
=== Evaluation result ===
Scheme: IBk
Options: -K 3 -W 0 -A "weka.core.neighboursearch.LinearNNSearch -A
\"weka.core.EuclideanDistance -R first-last\""
Relation: vote
Correctly Classified Instances 137
92.5676 %
Incorrectly Classified Instances 11
7.4324 %
Kappa statistic 0.849
Mean absolute error 0.0719
Root mean squared error 0.2099
Relative absolute error 15.0026 %
Root relative squared error 42.3302 %
Coverage of cases (0.95 level) 99.3243 %
Mean rel. region size (0.95 level) 57.4324 %
Total Number of Instances 148
=== Detailed Accuracy By Class ===
TP Rate FP Rate Precision Recall F-Measure ROC Area Class
0.907 0.048 0.963 0.907 0.934 0.988 democrat
0.952 0.093 0.881 0.952 0.915 0.988 republican
Avg. 0.926 0.067 0.928 0.926 0.926 0.988
=== Confusion Matrix ===
a b <-- classified as
78
8
| a = democrat
3
59
| b = republican
W tym przypadku również lepszy okazał się algorytm k-najbliższych sąsiadów.
Można jednak zauważyć, że zmniejszyła sie różnica w poprawności klasyfikacji
pomiędzy algorytmami. Graficzne przedstawienie w tym przypadku:
Wnioski: Ciężko jest jednoznacznie określić poprawność klasyfikatora,
ponieważ jak pokazują powyższe przykłady poprawność ta zależy w dużym
stopniu od tego jak został podzielony zbiór danych na dane uczące i dane
testowe. Można zauważyć większą poprawność dla obydwu klasyfikatorów przy
drugim podziale, jednak może to być spowodowane tym, że w zbiorze testowym
znajdowało się znacznie mniej danych. Co prawda dla klasyfikatora IBk różnica
ta jest nieznaczna, jednak dla NaiveBayes różnica jest bardziej zauważalna.
Można przypuszczać, że im więcej danych zostaje poddanych testowaniu tym
ocena klasyfikatora jest bardziej wiarygodna. Możemy się ośmielić wyciągnąć
wnioski, że dla naszego zbioru danych lepiej sprawdza się klasyfikator k-
najbliższych sąsiadów.
CZĘŚĆ 2
Teraz wykorzystamy program NetBeans i napiszemy program w Javie
odpowiadający wykonanemu w części 1 schematowi.
Rozpoczniemy od stworzenia nowego projektu o nazwie Projekt.java i wgraniu
biblioteki weka.jar.
Napisany kod ma postać:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package projekt;
import java.awt.BorderLayout;
import java.util.Random;
import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.evaluation.ThresholdCurve;
import weka.classifiers.lazy.IBk;
import weka.core.Instances;
import weka.core.Utils;
import weka.core.converters.ConverterUtils;
import weka.gui.visualize.PlotData2D;
import weka.gui.visualize.ThresholdVisualizePanel;
/**
*
* @author Ola
*/
public class Projekt {
public static void main(String[] args) throws Exception {
Instances daneIn = ConverterUtils.DataSource.read("C:/Program Files (x86)/Weka-3-7/data/vote.arff");
System.out.println("Informacje o oryginalnych danych: \n" + daneIn.toSummaryString());
System.out.println("Oryginalne dane: \n" + daneIn);
daneIn.setClassIndex(daneIn.numAttributes() - 1);
NaiveBayes(daneIn);
IBk(daneIn);
NaiveBayes2(daneIn);
IBk2(daneIn);
}
static void kroswalidacja(Instances daneIn, Classifier cla) throws Exception {
System.out.println("kroswalidacja krzyżowa:");
Evaluation ev = new Evaluation(daneIn);
ev.crossValidateModel(cla, daneIn, 3, new Random(1));
System.out.println(ev.toSummaryString("Podsumowanie:", false));
System.out.println(ev.toClassDetailsString("Szczegóły"));
System.out.println(ev.toMatrixString("Macierz błedów"));
krzywaROC(ev);
}
static void podzial(Instances daneIn, Classifier cla) throws Exception {
System.out.println("podział procentowy:");
double percent = 66.0;
int trainSize = (int) Math.round(daneIn.numInstances() * percent / 100);
int testSize = daneIn.numInstances() - trainSize;
Instances train = new Instances(daneIn, 0, trainSize);
Instances test = new Instances(daneIn, trainSize, testSize);
Evaluation ev = new Evaluation(train);
ev.evaluateModel(cla, test);
System.out.println(ev.toSummaryString("Podsumowanie:", false));
System.out.println(ev.toClassDetailsString("Szczegóły"));
System.out.println(ev.toMatrixString("Macierz błedów"));
krzywaROC(ev);
}
private static void NaiveBayes(Instances daneIn) throws Exception {
System.out.println("\n\nNaiveBayes...................................");
Classifier bayes = new NaiveBayes();
bayes.buildClassifier(daneIn);
kroswalidacja(daneIn, bayes);
}
private static void IBk(Instances daneIn) throws Exception {
System.out.println("\n\nIBk..........................................");
Classifier ibk = new IBk(3);
ibk.buildClassifier(daneIn);
kroswalidacja(daneIn, ibk);
}
private static void NaiveBayes2(Instances daneIn) throws Exception {
System.out.println("\n\nNaiveBayes...................................");
daneIn.randomize(new Random(1));
double percent = 66.0;
int trainSize = (int) Math.round(daneIn.numInstances() * percent / 100);
int testSize = daneIn.numInstances() - trainSize;
Instances train = new Instances(daneIn, 0, trainSize);
Instances test = new Instances(daneIn, trainSize, testSize);
Classifier bayes = new NaiveBayes();
bayes.buildClassifier(train);
podzial(daneIn, bayes);
}
private static void IBk2(Instances daneIn) throws Exception {
System.out.println("\n\nIBk..........................................");
double percent = 66.0;
int trainSize = (int) Math.round(daneIn.numInstances() * percent / 100);
int testSize = daneIn.numInstances() - trainSize;
Instances train = new Instances(daneIn, 0, trainSize);
Instances test = new Instances(daneIn, trainSize, testSize);
Classifier ibk = new IBk(3);
ibk.buildClassifier(train);
podzial(daneIn, ibk);
}
public static void krzywaROC(Evaluation eval) throws Exception {
ThresholdCurve tc = new ThresholdCurve();
int classIndex = 0;
Instances result = tc.getCurve(eval.predictions(), classIndex);
// System.out.println("Krzywa progowa:\n"+result);
ThresholdVisualizePanel vmc = new ThresholdVisualizePanel();
vmc.setROCString("(Pole poniżej ROC =" + Utils.doubleToString(tc.getROCArea(result), 4) + ")");
vmc.setName(result.relationName());
PlotData2D tempd = new PlotData2D(result);
tempd.setPlotName(result.relationName());
tempd.addInstanceNumberAttribute();
boolean[] cp = new boolean[result.numInstances()];
for (int n = 1; n < cp.length; n++) {
cp[n] = true;
tempd.setConnectPoints(cp);
}
vmc.addPlot(tempd);
String plotName = vmc.getName();
final javax.swing.JFrame jf = new javax.swing.JFrame("Weka Classifier Visualize" + plotName);
jf.setSize(500, 400);
jf.getContentPane().setLayout(new BorderLayout());
jf.getContentPane().add(vmc, BorderLayout.CENTER);
jf.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
jf.dispose();
}
});
jf.setVisible(true);
}
}
Dla porównania otrzymane wyniki są takie same jak w CZĘŚCI 1.
Dla CrossValidationFoldMaker
NaiveBayes
IBk
NaiveBayes...................................
kroswalidacja krzyżowa:
Podsumowanie:
Correctly Classified Instances 394
90.5747 %
Incorrectly Classified Instances 41
9.4253 %
Kappa statistic 0.8044
Mean absolute error 0.0979
Root mean squared error 0.2942
Relative absolute error 20.648 %
Root relative squared error 60.4328 %
Coverage of cases (0.95 level) 93.1034 %
Mean rel. region size (0.95 level) 53.3333 %
Total Number of Instances 435
Szczegóły
TP Rate FP Rate Precision Recall F-Measure ROC Area Class
0.895 0.077 0.948 0.895 0.921 0.971 democrat
0.923 0.105 0.847 0.923 0.883 0.971 republican
Avg. 0.906 0.088 0.909 0.906 0.906 0.971
Macierz błedów
a b <-- classified as
239
28
| a = democrat
13
155
| b = republican
IBk..........................................
kroswalidacja krzyżowa:
Podsumowanie:
Correctly Classified Instances 402
92.4138 %
Incorrectly Classified Instances 33
7.5862 %
Kappa statistic 0.8426
Mean absolute error 0.0825
Root mean squared error 0.2363
Relative absolute error 17.3873 %
Root relative squared error 48.5258 %
Coverage of cases (0.95 level) 97.7011 %
Mean rel. region size (0.95 level) 58.1609 %
Total Number of Instances 435
Szczegóły
TP Rate FP Rate Precision Recall F-Measure ROC Area Class
0.91 0.054 0.964 0.91 0.936 0.975 democrat
0.946 0.09 0.869 0.946 0.906 0.975 republican
Avg. 0.924 0.068 0.927 0.924 0.925 0.975
Macierz błedów
a b <-- classified as
243
24
| a = democrat
9
159
| b = republican
Dla TrainTestSplitMaker
NaiveBayes
IBk
NaiveBayes...................................
podział procentowy:
Podsumowanie:
Correctly Classified Instances 135
91.2162 %
Incorrectly Classified Instances 13
8.7838 %
Kappa statistic 0.8232
Mean absolute error 0.0912
Root mean squared error 0.2858
Relative absolute error 19.04 %
Root relative squared error 57.6557 %
Coverage of cases (0.95 level) 93.2432 %
Mean rel. region size (0.95 level) 53.0405 %
Total Number of Instances 148
Szczegóły
TP Rate FP Rate Precision Recall F-Measure ROC Area Class
0.872 0.032 0.974 0.872 0.92 0.98 democrat
0.968 0.128 0.845 0.968 0.902 0.98 republican
Avg. 0.912 0.072 0.92 0.912 0.913 0.98
Macierz błedów
a b <-- classified as
75
11
| a = democrat
2
60
| b = republican
IBk..........................................
podział procentowy:
Podsumowanie:
Correctly Classified Instances 137
92.5676 %
Incorrectly Classified Instances 11
7.4324 %
Kappa statistic 0.849
Mean absolute error 0.0719
Root mean squared error 0.2099
Relative absolute error 15.0026 %
Root relative squared error 42.3302 %
Coverage of cases (0.95 level) 99.3243 %
Mean rel. region size (0.95 level) 57.4324 %
Total Number of Instances 148
Szczegóły
TP Rate FP Rate Precision Recall F-Measure ROC Area Class
0.907 0.048 0.963 0.907 0.934 0.988 democrat
0.952 0.093 0.881 0.952 0.915 0.988 republican
Avg. 0.926 0.067 0.928 0.926 0.926 0.988
Macierz błedów
a b <-- classified as
78
8
| a = democrat
3
59
| b = republican