Java Projekt2

Politechnika Łódzka

Wydział Fizyki Technicznej, Informatyki i Matematyki Stosowanej

Kierunek: Matematyka

Specjalność: Analiza Danych w Biznesie i Logistyce

Projekt z przedmiotu

Techniki Analizy Danych

Poprawność klasyfikacji danych w oparciu o różne drzewa decyzyjne

Anna Ociepa

Łukasz Cichoszewski

Łódź, styczeń 2014

1. Wstęp

1.1. Cel projektu

Celem naszego projektu jest porównanie czterech drzew decyzyjnych:

Dokonamy tego wykorzystując środowisko Weka KnowledgeFlow oraz program NetBeans, w którym zaprezentujemy kod napisany w języku Java.

1.2. Dane

Dzięki uprzejmości Zakładu Doświadczalnego Oceny Odmian w Lućmierzu, na potrzeby projektu, otrzymaliśmy arkusze ze szczegółowymi danymi dotyczącymi badań nad udoskonalaniem odmianami papryki szklarniowej na przestrzeni lat od 2006 do 2013.

Z otrzymanych danych wyselekcjonowaliśmy kilka odmian papryki (Roxana, Redonna, Ozarowska, ShyBeauty, Aristotle ,King Arthur, Pancho, Elf Zielonki, Ristra, Roei) które były poddawana badaniom przez wszystkie lata. Każda roślina wraz owocem tej samej odmiany były poddawane szczegółowym pomiarom obejmującym następujące cechy rośliny:

LISC - DLUGOSC BLASZKI LISC - SZEROKOSC BLASZKI ROSLINA - DLUGOSC LODYGI ROSLINA - DLUGOSC MIEDZYWEZLI OWOC - DLUGOSC OWOC - SREDNICA OWOC - STOSUNEK DLUGOSCI DO SREDNICY

Mamy więc 7 atrybutów oraz dodatkowy atrybut klasowy – ODMIANA (z jakiej pochodzi dana roślina).Łączna ilość instancji 2000.

Dane otrzymane w formacie Excel przekonwertowaliśmy za pomocą Weki na format .arff.

Dane te znajdują się w pliku „papryka - pomiary.arff”.

2. Wybrane rodzaje drzew decyzyjnych

Zaczniemy od krótkich informacji na temat klasyfikatorów, z których będziemy korzystać.

2.1. J48

“Pruning” (cięcie) to technika, która redukuje rozmiar drzewa decyzyjnego, poprzez usuwanie sekcji drzewa, które są mało istotne przy klasyfikacji instancji. Kolejnym celem „cięcia” jest zmniejszona złożoność końcowego klasyfikatora oraz zwiększona dokładność predykcyjna poprzez redukcję przeuczenia i usunięcie części klasyfikatora, które mogą być oparte na szumnych lub błędnych danych.

Algorytm C 4.5 dzieli pierwotny zestaw danych względem każdej ze zmiennych. W ten sposób powstaje tyle wariantów podziału, ile w zestawie jest zmiennych objaśniających. Dla każdego podziału liczona jest wartość metryki information gain (zysk informacyjny), która zdefiniowana jest jako przyrost entropii (funkcja przyrostu informacji) uzyskanych podzbiorów w stosunku do zbioru pierwotnego w każdym z podzbiorów. Zmienna o najwyższym współczynniku information gain staje się pierwszym węzłem drzewa. Następnie dla wszystkich podzbiorów powtarza się tę operację aż do wyczerpania wszystkich instancji.

2.2. LMT

2.3. NBTree

2.4. RandomForest

3. Tworzenie projektu w Weka KnowledgeFlow

W tej części zajmiemy się utworzeniem projektu w środowisku Weka KnowledgeFlow. W tym celu wykonujemy następujące kroki:

3.1. Wczytanie danych z pliku

Z folderu DataSources wybieramy i umieszczamy w przestrzeni roboczej ArffLoader, dzięki czemu będziemy mogli korzystać z pliku o rozszerzeniu .arff . Następnie wczytujemy nasze dane, które znajdują się w pliku „papryka - pomiary.arff”. Aby obejrzeć graficzne przestawienie danych, z folderu Visualization wybieramy DataVisualizer i przesyłamy dataSet z ArffLoader do DataVisualizer.

3.2. Wybór atrybutu klasowego

Aby wybrać atrybut klasowy dla naszych danych, z folderu Visualization wybieramy ClassAssigner. Dalej przesyłamy dataSet z ArffLoader do ClassAssigner. Ustawiamy ostatni atrybut jako klasowy (ODMIANA), zatem w polu classColumn wpisujemy „last”.

3.3. Podział danych na zbiór testowy i uczący

  1. Zrobimy to poprzez podział procentowy. Z folderu Evaluation wybieramy TrainTestSplitMaker. Przesyłamy dataSet z CrossAssigner do TrainTestSplitMaker, a następnie w ustawieniach TrainTestSplitMaker w polu trainPercent wpisujemy jaki procent danych ma być zbiorem uczącym, w naszym przypadku 80.0. W przypadku kodu w języku java decyduje o tym wartość parametru „percent”.

Aby zobaczyć w jaki sposób dane zostały podzielone za pomocą TrainTestSplitMaker trzeba z folderu Visualization wybrać dwukrotnie TextViewer do jednego przesłać trainingSet, a do drugiego testSet.

  1. Alternatywnie skorzystamy z k-krotnej kroswalidacji. Z folderu Evaluation wybieramy CrossValidationFoldMaker. Przesyłamy dataSet z CrossAssigner do CrossValidationFoldMaker, a następnie w ustawieniach CrossValidationFoldMaker w polu folds wpisujemy liczbę na ile podzbiorów mają zostać podzielone dane, w naszym przypadku 4. W przypadku kodu w języku java decyduje o tym wartość parametru „krotnosc”.

Aby zobaczyć w jaki sposób dane zostały podzielone za pomocą CrossValidationFoldMaker trzeba z folderu Visualization wybrać dwukrotnie TextViewer do jednego przesłać trainingSet, a do drugiego testSet.

Oryginalne dane dzielone są na k-podzbiorów. Następnie kolejno każdy z nich bierze się jako zbiór testowy, a pozostałe razem jako zbiór uczący i wykonuje klasyfikację. Przyporządkowanie jest wykonywane tu k-razy a wynik końcowy jest ich średnią. Dzięki temu tak otrzymany wynik jest bardziej wiarygodny niż dokonanie procentowego podział danych.

3.4. Wybór i modyfikacja klasyfikatorów

Sklasyfikujemy teraz dane za pomocą czterech różnych klasyfikatorów (wymienionych wcześniej drzew decyzyjnych):

Z folderu Classifiers wybieramy podfolder trees, a następnie kolejne drzewa. Z TrainTestSplitMaker przesyłamy trainingSet i testSet do każdego z nich.

W każdym z drzew możemy dowolnie modyfikować parametry. Dla przykładu wykonamy modyfikację drzewa J48 oraz RandomForest.

W przypadku drzewa J48 zmienione parametry to:

  1. confidenceFactor -- The confidence factor used for pruning (smaller values incur more pruning). [z domyślnego 0.25 na 0.15]

  2. minNumObj -- The minimum number of instances per leaf. [z domyślnego 3 na 10]

W przypadku RandomForest zmieniony parametr to:

  1. numTrees -- The number of trees to be generated. [z domyślnego 10 na 30]

3.5. Ocena klasyfikacji

Aby ocenić poprawność klasyfikacji dla każdego z klasyfikatorów, z folderu Evaluation wybieramy ClassifierPerrformanceEvaluator i z każdego drzewa decyzyjnego przesyłamy do niego batchClasifier.

3.6. Wyświetlanie wyniku ewaluacji

Aby wyświetlić efekty klasyfikacji w formie tekstowej z folderu Visualization musimy wybrać TextViewer i przesłać do niego text z ClassifierPerrformanceEvaluator

Aby wyświetlić efekty klasyfikacji w formie graficznej z folderu Visualization musimy wybrać ModelPerformanceChart i przesłać do niego thresholdData z ClassifierPerrformanceEvaluator.

Ostateczny projekt wygląda następująco:

  1. Kroswalidacja danych:

  2. Procentowy podział danych

3.7. Podsumowanie i porównanie otrzymanych wyników

Aby uruchomić schemat wystarczy kliknąć strzałkę (Run thisflow/Start loading) w lewym górnym rogu. Możemy teraz zobaczyć wyniki ewaluacji.

Klikając prawym przyciskiem myszy na TextViewer wybieramy Show results. Dla każdego z drzew wyświetlają nam się wyniki. Zestawienie otrzymanych wyników dla podziału procentowego danych.

  1. Dla 80% podziału danych: 2) Dla 4 krotnej kroswalidacji:

=== Evaluation result ===

Scheme: J48

Options: -C 0.15 -M 10

Relation: papryka - pomiary

Correctly Classified Instances 312 78 %

Incorrectly Classified Instances 88 22 %

Kappa statistic 0.7557

Mean absolute error 0.0578

Root mean squared error 0.1857

Relative absolute error 32.0848 %

Root relative squared error 61.8598 %

Total Number of Instances 400

=== Detailed Accuracy By Class ===

TP Rate FP Rate Precision Recall F-Measure ROC Area Class

0.558 0.023 0.784 0.558 0.652 0.914 Roxana

0.714 0.003 0.968 0.714 0.822 0.936 Redonna

0.571 0.058 0.488 0.571 0.526 0.84 Ozarowska

0.421 0.036 0.552 0.421 0.478 0.836 ShyBeauty

0.818 0.057 0.563 0.818 0.667 0.951 Aristotle

0.868 0.022 0.805 0.868 0.835 0.986 King Arthur

1 0.006 0.951 1 0.975 0.997 Pancho

0.932 0.014 0.891 0.932 0.911 0.96 Elf Zielonki

0.977 0.006 0.955 0.977 0.966 0.998 Ristra

0.972 0.019 0.833 0.972 0.897 0.992 Roei

Weighted Avg. 0.78 0.023 0.79 0.78 0.777 0.942

=== Confusion Matrix ===

a b c d e f g h i j <-- classified as

29 0 3 4 9 4 0 2 0 1 | a = Roxana

1 30 8 1 1 0 1 0 0 0 | b = Redonna

0 1 20 4 4 0 1 1 1 3 | c = Ozarowska

3 0 9 16 4 4 0 1 0 1 | d = Shy Beauty

1 0 0 4 27 0 0 0 0 1 | e = Aristotle

2 0 0 0 3 33 0 0 0 0 | f = King Arthur

0 0 0 0 0 0 39 0 0 0 | g = Pancho

1 0 0 0 0 0 0 41 1 1 | h = Elf Zielonki

0 0 0 0 0 0 0 1 42 0 | i = Ristra

0 0 1 0 0 0 0 0 0 35 | j = Roei

=== Evaluation result ===

Scheme: J48

Options: -C 0.15 -M 10

Relation: papryka - pomiary

Correctly Classified Instances 1569 78.45 %

Incorrectly Classified Instances 431 21.55 %

Kappa statistic 0.7606

Mean absolute error 0.0551

Root mean squared error 0.1794

Relative absolute error 30.5855 %

Root relative squared error 59.8026 %

Total Number of Instances 2000

=== Detailed Accuracy By Class ===

TP Rate FP Rate Precision Recall F-Measure ROC Area Class

0.555 0.043 0.59 0.555 0.572 0.906

Roxana

0.705 0.023 0.77 0.705 0.736 0.927 Redonna

0.535 0.027 0.686 0.535 0.601 0.869 Ozarowska

0.735 0.039 0.677 0.735 0.705 0.936 ShyBeauty

0.745 0.036 0.7 0.745 0.722 0.946

Aristotle

0.885 0.019 0.839 0.885 0.861 0.988 King Arthur

0.995 0.004 0.961 0.995 0.978 0.995 Pancho

0.87 0.017 0.849 0.87 0.859 0.977 Elf Zielonki

0.935 0.016 0.866 0.935 0.899 0.987 Ristra

0.885 0.015 0.868 0.885 0.876 0.992 Roei

Weighted Avg. 0.785 0.024 0.781 0.785 0.781 0.952

=== Confusion Matrix ===

a b c d e f g h i j <-- classified as

111 6 3 25 26 16 0 8 0 5 | a = Roxana

5 141 31 5 3 0 1 5 6 3 | b = Redonna

10 28 107 12 11 0 4 8 8 12 | c = Ozarowska

28 1 4 147 9 7 3 0 0 1 | d = Shy Beauty

15 0 1 21 149 11 0 1 0 2 | e = Aristotle

6 0 0 7 10 177 0 0 0 0 | f = King Arthur

0 0 0 0 0 0 199 1 0 0 | g = Pancho

3 0 4 0 0 0 0 174 15 4 | h = Elf Zielonki

0 6 0 0 0 0 0 7 187 0 | i = Ristra

10 1 6 0 5 0 0 1 0 177 | j = Roei

  1. Dla 80% podziału danych: 2) Dla 4 krotnej kroswalidacji:

=== Evaluation result ===

Scheme: LMT

Options: -I -1 -M 15 -W 0.0

Relation: papryka - pomiary

Correctly Classified Instances 335 83.75 %

Incorrectly Classified Instances 65 16.25 %

Kappa statistic 0.8195

Mean absolute error 0.0329

Root mean squared error 0.1733

Relative absolute error 18.2807 %

Root relative squared error 57.7214 %

Total Number of Instances 400

=== Detailed Accuracy By Class ===

TP Rate FP Rate Precision Recall F-Measure ROC Area Class

0.5 0.014 0.839 0.5 0.627 0.868 Roxana

0.833 0.042 0.7 0.833 0.761 0.935 Redonna

0.686 0.025 0.727 0.686 0.706 0.878 Ozarowska

0.658 0.03 0.694 0.658 0.676 0.841 Shy Beauty

0.97 0.041 0.681 0.97 0.8 0.971 Aristotle

0.895 0.017 0.85 0.895 0.872 0.978 King Arthur

1 0 1 1 1 1 Pancho

0.932 0.003 0.976 0.932 0.953 0.985 Elf Zielonki

1 0.003 0.977 1 0.989 0.999 Ristra

1 0.005 0.947 1 0.973 0.998 Roei

Weighted Avg. 0.838 0.017 0.844 0.838 0.832 0.944

=== Confusion Matrix ===

a b c d e f g h i j <-- classified as

26 5 2 8 6 4 0 1 0 0 | a = Roxana

1 35 4 1 1 0 0 0 0 0 | b = Redonna

1 5 24 2 3 0 0 0 0 0 | c = Ozarowska

2 4 2 25 2 2 0 0 0 1 | d = Shy Beauty

0 0 1 0 32 0 0 0 0 0 | e = Aristotle

1 0 0 0 3 34 0 0 0 0 | f = King Arthur

0 0 0 0 0 0 39 0 0 0 | g = Pancho

0 1 0 0 0 0 0 41 1 1 | h = Elf Zielonki

0 0 0 0 0 0 0 0 43 0 | i = Ristra

0 0 0 0 0 0 0 0 0 36 | j = Roei

=== Evaluation result ===

Scheme: LMT

Options: -I -1 -M 15 -W 0.0

Relation: papryka - pomiary

Correctly Classified Instances 1279 85.2667 %

Incorrectly Classified Instances 221 14.7333 %

Kappa statistic 0.8363

Mean absolute error 0.0323

Root mean squared error 0.1615

Relative absolute error 17.968 %

Root relative squared error 53.84 %

Total Number of Instances 1500

=== Detailed Accuracy By Class ===

TP Rate FP Rate Precision Recall F-Measure ROC Area Class

0.62 0.027 0.715 0.62 0.664 0.918

Roxana

0.807 0.019 0.829 0.807 0.818 0.943 Redonna

0.74 0.018 0.822 0.74 0.779 0.933 Ozarowska

0.727 0.035 0.699 0.727 0.712 0.928 ShyBeauty

0.84 0.029 0.764 0.84 0.8 0.975 Aristotle

0.92 0.015 0.873 0.92 0.896 0.986

King Arthur

1 0.002 0.98 1 0.99 0.999 Pancho

0.92 0.01 0.914 0.92 0.917 0.994 Elf Zielonki

0.953 0.004 0.96 0.953 0.957 0.996 Ristra

1 0.005 0.955 1 0.977 0.999 Roei

Weighted Avg. 0.853 0.016 0.851 0.853 0.851 0.967

=== Confusion Matrix ===

a b c d e f g h i j <-- classified as

93 6 3 19 17 10 0 2 0 0 | a = Roxana

4 121 15 3 4 0 0 2 0 1 | b = Redonna

2 14 111 10 4 2 0 2 0 5 | c = Ozarowska

15 3 3 109 12 5 3 0 0 0 | d = Shy Beauty

11 0 0 10 126 3 0 0 0 0 | e = Aristotle

5 0 0 5 2 138 0 0 0 0 | f = King Arthur

0 0 0 0 0 0 150 0 0 0 | g = Pancho

0 2 3 0 0 0 0 138 6 1 | h = Elf Zielonki

0 0 0 0 0 0 0 7 143 0 | i = Ristra

0 0 0 0 0 0 0 0 0 150 | j = Roei

  1. Dla 80% podziału danych: 2) Dla 4 krotnej kroswalidacji:

=== Evaluation result ===

Scheme: NBTree

Relation: papryka - pomiary

Correctly Classified Instances 320 80 %

Incorrectly Classified Instances 80 20 %

Kappa statistic 0.7776

Mean absolute error 0.0642

Root mean squared error 0.1752

Relative absolute error 35.6536 %

Root relative squared error 58.3648 %

Total Number of Instances 400

=== Detailed Accuracy By Class ===

TP Rate FP Rate Precision Recall F-Measure ROC Area Class

0.558 0.052 0.617 0.558 0.586 0.908 Roxana

0.69 0.022 0.784 0.69 0.734 0.912 Redonna

0.629 0.03 0.667 0.629 0.647 0.904 Ozarowska

0.658 0.036 0.658 0.658 0.658 0.894 ShyBeauty

0.848 0.033 0.7 0.848 0.767 0.983 Aristotle

0.842 0.033 0.727 0.842 0.78 0.983 King Arthur

1 0 1 1 1 1 Pancho

0.864 0.006 0.95 0.864 0.905 0.968 Elf Zielonki

0.977 0.008 0.933 0.977 0.955 0.989 Ristra

1 0.003 0.973 1 0.986 1 Roei

Weighted Avg. 0.8 0.023 0.8 0.8 0.798 0.953

=== Confusion Matrix ===

a b c d e f g h i j <-- classified as

29 0 1 7 6 7 0 0 1 1 | a = Roxana

1 29 8 2 1 0 0 1 0 0 | b = Redonna

3 3 22 3 4 0 0 0 0 0 | c = Ozarowska

5 3 0 25 1 4 0 0 0 0 | d = Shy Beauty

2 0 2 1 28 0 0 0 0 0 | e = Aristotle

5 1 0 0 0 32 0 0 0 0 | f = King Arthur

0 0 0 0 0 0 39 0 0 0 | g = Pancho

2 1 0 0 0 1 0 38 2 0 | h = Elf Zielonki

0 0 0 0 0 0 0 1 42 0 | i = Ristra

0 0 0 0 0 0 0 0 0 36 | j = Roei

=== Evaluation result ===

Scheme: NBTree

Relation: papryka - pomiary

Correctly Classified Instances 1669 83.45 %

Incorrectly Classified Instances 331 16.55 %

Kappa statistic 0.8161

Mean absolute error 0.0598

Root mean squared error 0.1639

Relative absolute error 33.2072 %

Root relative squared error 54.6313 %

Total Number of Instances 2000

=== Detailed Accuracy By Class ===

TP Rate FP Rate Precision Recall F-Measure ROC Area Class

0.61 0.031 0.689 0.61 0.647 0.906

Roxana

0.72 0.02 0.8 0.72 0.758 0.941 Redonna

0.76 0.036 0.704 0.76 0.731 0.939 Ozarowska

0.745 0.031 0.73 0.745 0.738 0.931 ShyBeauty

0.835 0.027 0.773 0.835 0.803 0.968 Aristotle

0.9 0.017 0.857 0.9 0.878 0.979

King Arthur

0.98 0.001 0.995 0.98 0.987 0.998 Pancho

0.88 0.014 0.876 0.88 0.878 0.971 Elf Zielonki

0.925 0.003 0.974 0.925 0.949 0.98 Ristra

0.99 0.006 0.947 0.99 0.968 1 Roei

Weighted Avg. 0.835 0.018 0.835 0.835 0.834 0.961

=== Confusion Matrix ===

a b c d e f g h i j <-- classified as

122 8 15 21 17 15 0 2 0 0 | a = Roxana

5 144 31 10 1 2 1 1 0 5 | b = Redonna

6 20 152 4 8 0 0 6 0 4 | c = Ozarowska

20 2 5 149 14 7 0 1 1 1 | d = Shy Beauty

7 2 4 13 167 6 0 0 0 1 | e = Aristotle

8 0 0 5 7 180 0 0 0 0 | f = King Arthur

2 1 1 0 0 0 196 0 0 0 | g = Pancho

7 3 6 2 2 0 0 176 4 0 | h = Elf Zielonki

0 0 2 0 0 0 0 13 185 0 | i = Ristra

0 0 0 0 0 0 0 2 0 198 | j = Roei

  1. Dla 80% podziału danych: 2) Dla 4 krotnej kroswalidacji:

=== Evaluation result ===

Scheme: RandomForest

Options: -I 30 -K 0 -S 1

Relation: papryka - pomiary

Correctly Classified Instances 347 86.75 %

Incorrectly Classified Instances 53 13.25 %

Kappa statistic 0.8528

Mean absolute error 0.0419

Root mean squared error 0.1396

Relative absolute error 23.2576 %

Root relative squared error 46.4977 %

Total Number of Instances 400

=== Detailed Accuracy By Class ===

TP Rate FP Rate Precision Recall F-Measure ROC Area Class

0.577 0.02 0.811 0.577 0.674 0.968 Roxana

0.833 0.025 0.795 0.833 0.814 0.974 Redonna

0.771 0.022 0.771 0.771 0.771 0.977 Ozarowska

0.789 0.03 0.732 0.789 0.759 0.969 ShyBeauty

0.97 0.033 0.727 0.97 0.831 0.997 Aristotle

0.895 0.008 0.919 0.895 0.907 0.997 King Arthur

1 0 1 1 1 1 Pancho

0.932 0.003 0.976 0.932 0.953 0.999 Elf Zielonki

1 0.003 0.977 1 0.989 1 Ristra

1 0.003 0.973 1 0.986 1 Roei

Weighted Avg. 0.868 0.014 0.871 0.868 0.865 0.988

=== Confusion Matrix ===

a b c d e f g h i j <-- classified as

30 3 1 8 6 3 0 1 0 0 | a = Roxana

0 35 6 0 1 0 0 0 0 0 | b = Redonna

2 2 27 2 2 0 0 0 0 0 | c = Ozarowska

2 4 1 30 1 0 0 0 0 0 | d = ShyBeauty

0 0 0 1 32 0 0 0 0 0 | e = Aristotle

2 0 0 0 2 34 0 0 0 0 | f = King Arthur

0 0 0 0 0 0 39 0 0 0 | g = Pancho

1 0 0 0 0 0 0 41 1 1 | h = Elf Zielonki

0 0 0 0 0 0 0 0 43 0 | i = Ristra

0 0 0 0 0 0 0 0 0 36 | j = Roei

=== Evaluation result ===

Scheme: RandomForest

Options: -I 30 -K 0 -S 1

Relation: papryka - pomiary

Correctly Classified Instances 1789 89.45 %

Incorrectly Classified Instances 211 10.55 %

Kappa statistic 0.8828

Mean absolute error 0.0382

Root mean squared error 0.1269

Relative absolute error 21.2278 %

Root relative squared error 42.2934 %

Total Number of Instances 2000

=== Detailed Accuracy By Class ===

TP Rate FP Rate Precision Recall F-Measure ROC Area Class

0.73 0.018 0.816 0.73 0.77 0.973 Roxana

0.81 0.014 0.866 0.81 0.837 0.981 Redonna

0.76 0.019 0.813 0.76 0.786 0.978 Ozarowska

0.82 0.019 0.828 0.82 0.824 0.989 ShyBeauty

0.92 0.019 0.84 0.92 0.878 0.995 Aristotle

0.97 0.011 0.911 0.97 0.939 0.998 King Arthur

1 0 1 1 1 1 Pancho

0.96 0.011 0.91 0.96 0.934 0.999 Elf Zielonki

0.975 0.003 0.97 0.975 0.973 0.999 Ristra

1 0.003 0.976 1 0.988 1 Roei

Weighted Avg. 0.895 0.012 0.893 0.895 0.893 0.991

=== Confusion Matrix ===

a b c d e f g h i j <-- classified as

146 3 6 16 15 11 0 3 0 0 | a = Roxana

3 162 24 4 1 0 0 5 0 1 | b = Redonna

6 19 152 9 3 1 0 6 0 4 | c = Ozarowska

14 1 4 164 12 5 0 0 0 0 | d = Shy Beauty

6 2 1 5 184 2 0 0 0 0 | e = Aristotle

2 0 0 0 4 194 0 0 0 0 | f = King Arthur

0 0 0 0 0 0 200 0 0 0 | g = Pancho

2 0 0 0 0 0 0 192 6 0 | h = Elf Zielonki

0 0 0 0 0 0 0 5 195 0 | i = Ristra

0 0 0 0 0 0 0 0 0 200 | j = Roei

Popatrzmy teraz na macierz ConfusionMatrix. W wierszach znajdują się wartości prognozowane, w kolumnach zaś empiryczne. Na uwagę zasługują wartości elementów na głównej przekątnej, które znacznie przewyższają wartości pozostałych komórek, oznaczających poprawnie sklasyfikowane instancje, co przemawia na rzecz dużej trafności drzewa decyzyjnego.

Spójrzmy teraz na porównanie ilości poprawnie i niepoprawnie sklasyfikowanych instancji dla każdego drzewa decyzyjnego:

PODZIAŁ J48 LMT NBTree RandomForest

Correctly

Classified

Instances

312 78.0% 334 83.75 % 320 80 % 347 86.75%

Incorrectly

Classified

Instances

88 22.0 % 66 16.25 % 80 20 % 53 13.25 %

wielkość danych testowych – 400

KROSWALIDACJA J48 *LMT NBTree RandomForest

Correctly

Classified

Instances

1569 78.45 % 1279 85.27% 1669 83.45% 1789 89.45 %

Incorrectly

Classified

Instances

431 21.55 % 221 14.73 % 331 16.55 % 211 10.55 %

* wielkość danych obcięta do 1500 instancji (pozostałe 2000).

Odczytując wyniki z powyższej tabeli możemy wnioskować, że najlepsze jest użycie drzewa RandomForest, gdyż w przypadku tego klasyfikatora otrzymujemy największą ilość poprawnie sklasyfikowanych instancji.

3.8. Graficzne przedstawienie wyników

Możemy również obejrzeć graficzne przedstawienie powyższych wyników. W tym celu musimy kliknąć prawym przyciskiem myszy na ModelPerformanceChart i wybrać Show chart. Wyświetla nam się:

Dobrą jakość wygenerowanego drzewa potwierdza krzywa ROC (Receiver Operating Characteristic).Warto zwrócić uwagę na jej pożądany wygląd – wyraźna wklęsłość, która świadczy o dużej trafności klasyfikacji dla każdego z klasyfikatorów.

4. Projekt w programie NetBeans w języku Java

Teraz wykorzystamy program NetBeans i napiszemy kod w języku Java odpowiadający wykonanemu w programie Weka schematowi.

Możemy zauważyć, że otrzymane wyniki są takie same jak w części, gdzie tworzyliśmy projekt w programie Weka.

Napisany przez nas kod ma następującą postać:

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package DrzewaDecyzyjne;

import java.awt.BorderLayout;

import weka.classifiers.Classifier;

import weka.classifiers.Evaluation;

import weka.classifiers.evaluation.ThresholdCurve;

import weka.classifiers.trees.J48;

import weka.classifiers.trees.LMT;

import weka.classifiers.trees.NBTree;

import weka.classifiers.trees.RandomForest;

import weka.core.Debug.Random;

import weka.core.Instances;

import weka.core.Utils;

import weka.core.converters.ConverterUtils;

import weka.gui.visualize.PlotData2D;

import weka.gui.visualize.ThresholdVisualizePanel;

/**

*

* @author Luk@s

*/

public class DrzewaDecyzyjne {

public static void main(String[] args) throws Exception {

Instances daneIn = ConverterUtils.DataSource.read("C:/papryka - pomiary.arff"); // wczytanie danych

// System.out.println("Oryginalne dane:\n" + daneIn); //wyswietlanie oryginalnych danych

System.out.println(daneIn.toSummaryString()); //wyciaga tytul atrybutów, typ i inne dane - w tabelce

daneIn.setClassIndex(daneIn.numAttributes() - 1); // ustwianie atrybutu klasowego

double percent = 80; //ustawianie procentowego podzialu danych

int krotnosc = 4; //ustawienie krotnosci kroswalidacji

//**Wybór opcji do wyswietlania:**\\

int wybor = 1; // 1 - podzial danych 2- krswalidacja //

if (wybor == 1) {

J48(daneIn, percent);

LMT(daneIn, percent);

NBTree(daneIn, percent);

RandomForest(daneIn, percent);

} else if (wybor == 2) {

J48Kroswalidacja(daneIn, krotnosc);

LMTKroswalidacja(daneIn, krotnosc);

NBTreeKroswalidacja(daneIn, krotnosc);

RandomForestKroswalidacja(daneIn, krotnosc);

}

}

public static void podzial(Instances daneIn, Classifier cla, double percent) throws Exception {

System.out.println("\nPodzial procentowy danych:" + "\n");

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("Wielkosc próby uczacej:" + trainSize + " czyli " + percent + "% danych poczatkowych");

System.out.println("Wielkosc próby testowej:" + testSize + "\n");

System.out.println(ev.toSummaryString("Podsumowanie:\n", false));

System.out.println(ev.toClassDetailsString("Szczególy:"));

System.out.println(ev.toMatrixString("Macierz bledów:\n"));

// krzywaROC(ev);

}

static void Kroswalidacja(Instances daneIn, Classifier cla, int krotnosc) throws Exception {

System.out.println("Kroswalidacja: " + "krotnosc kroswalidacji wynosi - " + krotnosc + "\n");

Evaluation ev = new Evaluation(daneIn);

ev.crossValidateModel(cla, daneIn, krotnosc, new Random(1));

System.out.println(ev.toSummaryString("Podsumowanie:\n", false));

System.out.println(ev.toClassDetailsString("Szczególy"));

System.out.println(ev.toMatrixString("Macierz bledów\n"));

//krzywaROC(ev);

}

private static void J48(Instances daneIn, double percent) throws Exception {

System.out.println("\n......................##.....J48..'C4.5 decision tree'...##......................\n");

daneIn.randomize(new Random(1));

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 j48 = new J48();

System.out.println("Opcje domyslne:");

String[] opcje = j48.getOptions();

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

System.out.println("Zmieniono na:");

opcje[0] = "-C"; //Set confidence threshold for pruning (default 0.25)

opcje[1] = "0.15";

opcje[2] = "-M"; //Set minimum number of instances per leaf

opcje[3] = "10";

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

j48.setOptions(opcje);

j48.buildClassifier(train);

// System.out.println(j48); //wyswietlanie wygladu drzewa

podzial(daneIn, j48, percent);

}

private static void J48Kroswalidacja(Instances daneIn, int krotnosc) throws Exception {

System.out.println("\n......................##.....J48..'C4.5 decision tree'...##......................\n");

Classifier j48 = new J48();

System.out.println("Opcje domyslne:");

String[] opcje = j48.getOptions();

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

//

System.out.println("Zmieniono na:");

opcje[0] = "-C"; //Set confidence threshold for pruning (default 0.25)

opcje[1] = "0.15";

opcje[2] = "-M"; //Set minimum number of instances per leaf

opcje[3] = "10";

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

j48.setOptions(opcje);

j48.buildClassifier(daneIn);

Kroswalidacja(daneIn, j48, krotnosc);

}

private static void LMT(Instances daneIn, double percent) throws Exception {

System.out.println("\n......................##.....LMT.'logistic model trees'....##......................\n");

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 LMT = new LMT();

System.out.println("Opcje domyslne:");

String[] opcje = LMT.getOptions();

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

System.out.println("Zmieniono na:");

opcje[0] = "-I"; // Set fixed number of iterations for LogitBoost

opcje[1] = "-1";

opcje[2] = "-M"; //Set minimum number of instances at which a node can be split (default 15)

opcje[3] = "15";

opcje[4] = "-W"; //Set beta for weight trimming for LogitBoost. Set to 0 (default) for no weight trimming

opcje[5] = "0.0";

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

LMT.buildClassifier(train);

// System.out.println(LMT); //wyswietlanie wygladu drzewa

podzial(daneIn, LMT, percent);

}

private static void LMTKroswalidacja(Instances daneIn, int krotnosc) throws Exception {

System.out.println("\n......................##.....LMT.'logistic model trees'....##......................\n");

Classifier LMT = new LMT();

System.out.println("Opcje domyslne:");

String[] opcje = LMT.getOptions();

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

System.out.println("Zmieniono na:");

opcje[0] = "-I"; // Set fixed number of iterations for LogitBoost

opcje[1] = "-1";

opcje[2] = "-M"; //Set minimum number of instances at which a node can be split (default 15)

opcje[3] = "15";

opcje[4] = "-W"; //Set beta for weight trimming for LogitBoost. Set to 0 (default) for no weight trimming

opcje[5] = "0.0";

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

LMT.setOptions(opcje);

LMT.buildClassifier(daneIn);

Kroswalidacja(daneIn, LMT, krotnosc);

}

private static void NBTree(Instances daneIn, double percent) throws Exception {

System.out.println("\n...##.....Decision tree with naive Bayes classifiers.....##...\n");

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 NBTree = new NBTree();

NBTree.buildClassifier(train);

// System.out.println(NBTree); //wyswietlanie wygladu drzewa

podzial(daneIn, NBTree, percent);

}

private static void NBTreeKroswalidacja(Instances daneIn, int krotnosc) throws Exception {

System.out.println("\n...##.....Decision tree with naive Bayes classifiers.....##...\n");

Classifier NBTree = new NBTree();

NBTree.buildClassifier(daneIn);

Kroswalidacja(daneIn, NBTree, krotnosc);

}

private static void RandomForest(Instances daneIn, double percent) throws Exception {

System.out.println("\n......................##.....RandomForest.'forest of random trees'....##......................\n");

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 RandomForest = new RandomForest();

System.out.println("Opcje domyslne:");

String[] opcje = RandomForest.getOptions();

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

opcje[0] = "-I"; //Number of trees to build

opcje[1] = "30";

opcje[2] = "-K"; //Number of features to consider (<1=int(logM+1))

opcje[3] = "0";

opcje[4] = "-S"; //Seed for random number generator (default 1)

opcje[5] = "1";

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

RandomForest.setOptions(opcje);

RandomForest.buildClassifier(train);

// System.out.println(RandomForest); //wyswietlanie wygladu drzewa

podzial(daneIn, RandomForest, percent);

}

private static void RandomForestKroswalidacja(Instances daneIn, int krotnosc) throws Exception {

System.out.println("\n......................##.....RandomForest.'forest of random trees'....##......................\n");

Classifier RandomForest = new RandomForest();

System.out.println("Opcje domyslne:");

String[] opcje = RandomForest.getOptions();

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

System.out.println("Zmieniono na:");

opcje[0] = "-I"; //Number of trees to build

opcje[1] = "30";

opcje[2] = "-K"; //Number of features to consider (<1=int(logM+1))

opcje[3] = "0";

opcje[4] = "-S"; //Seed for random number generator (default 1)

opcje[5] = "1";

for (int i = 0; i < opcje.length; i++) {

if (opcje[i].length() > 0) {

System.out.println(i + ": " + opcje[i]);

}

}

RandomForest.setOptions(opcje);

RandomForest.buildClassifier(daneIn);

Kroswalidacja(daneIn, RandomForest, krotnosc);

}

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 ponizej 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);

}

}


Wyszukiwarka

Podobne podstrony:
Java Projekt
Projekt java
Inzynieria oprogramowania w ujeciu obiektowym UML wzorce projektowe i Java iowuje
Projekt java
JAVA tworzenie projektu
Java Programowanie, biblioteki open source i pomysly na nowe projekty
JAVA tworzenie projektu
Inżynieria oprogramowania w ujęciu obiektowym UML, wzorce projektowe i Java [PL]
Projekt java
Inzynieria oprogramowania w ujeciu obiektowym UML wzorce projektowe i Java iowuje
Java Wzorce projektowe
Java Wzorce projektowe javawz
Java Programowanie, biblioteki open source i pomysly na nowe projekty
Java Wzorce projektowe
Java Wzorce projektowe
Java Programowanie biblioteki open source i pomysly na nowe projekty

więcej podobnych podstron