Marcin Dobrowolski - podprojekt
This commit is contained in:
parent
d89e37e6eb
commit
55b9625189
@ -4,47 +4,36 @@
|
||||
**Temat:** Sugerowanie potraw
|
||||
**Metoda uczenia:** Decision Tree(CART)
|
||||
**Autor:** Marcin Jerzy Dobrowolski
|
||||
**Okres trwwania prac:** 29 kwietnia - 27 maja 2020
|
||||
**Źródła:** https://github.com/random-forests/tutorials/blob/master/decision_tree.ipynb
|
||||
|
||||
**Link do repozytorium projektu:** https://git.wmi.amu.edu.pl/s444427/Sztuczna_Inteligencja_2020
|
||||
|
||||
## Wstęp
|
||||
|
||||
Tematem realizowanego projektu jest stworzenie sztucznej inteligencji, która na podstawie podanych atrybutów stwierdzi jaka potrawa będzie najlepszym wyborem dla gościa restauaracji. Atrybuty odpowiadają na takie pytania jak:
|
||||
|
||||
* czy gość jest wegetarianinem? - {meat, vege}
|
||||
* jak bardzo chce się najeść/jak wielka ma być potrawa? - {small, regular, large}
|
||||
* ile gotówki może przeznaczyć na ten cel? - {<10;20>, <20;30>, <30;40>, <40;50>, <50;60>}
|
||||
* jak jaki jest jego apetyt? - {<10;25>, <25;40>, <40;55>}
|
||||
|
||||
Powyższymi atrybutami rządzą pewne zależności. Apetyt gościa ma wpływ na to jaka potrawa będzie dla niego mała, średnia bądź duża.
|
||||
|
||||
Do osiągnięcia celu wykorzystałem metodę drzew decyzyjnych CART oraz następujące biblioteki języka python:
|
||||
|
||||
* csv
|
||||
* random
|
||||
|
||||
## Uczenie modelu
|
||||
|
||||
### Zbiór uczący
|
||||
|
||||
Do zbudowania drzewa decyzyjnego wykorzystałem spreparowany przez siebie zbiór przykładów atrybutów gości z odpowiadającymi im daniami. Zawarte jest w nim 213 przykładów dotyczących 20 różnych potraw. Całość znajduje się w pliku: [trainingData.csv](src/SubprojectMarcinDobrowolski/Data/trainingData.csv)
|
||||
|
||||
### Moduły
|
||||
Projekt rozwiązuje problem zasugerowania dania przez kelnera na podstawie danych reprezentujących preferencje gościa. W tym celu wykorzystałem metodę uczenia drzew decyzyjnych CART, którą zaprogramowałem w czystym języku python. Struktura podprojektu:
|
||||
|
||||
* [suggestionDecisionTree.py](src/SubprojectMarcinDobrowolski/suggestionDecisionTree.py) - klasa drzew decyzyjnego
|
||||
* [question.py](src/SubprojectMarcinDobrowolski/question.py) - klasa pytania
|
||||
* [leaf.py](src/SubprojectMarcinDobrowolski/leaf.py) - klasa liścia
|
||||
* [decisionNode.py](src/SubprojectMarcinDobrowolski/decisionNode.py) - klasa wierzchołka
|
||||
* [decisionNode.py](src/SubprojectMarcinDobrowolski/decisionNode.py) - klasa wierzchołka pytającego
|
||||
* [utility.py](src/SubprojectMarcinDobrowolski/utility.py) - klasa użytkowa
|
||||
* [testData.csv](src/SubprojectMarcinDobrowolski/Data/testData.csv) - zbiór testowy
|
||||
* [trainingData.csv](src/SubprojectMarcinDobrowolski/Data/trainingData.csv) - zbiór uczący
|
||||
* [testData.csv](src/SubprojectMarcinDobrowolski/Data/testData.csv) - klasa użytkowa
|
||||
|
||||
Struktura danych reprezentujących preferencje gościa:
|
||||
|
||||
type, size, money, appetite, name
|
||||
['meat', 'small', 31, 55, 'schabowy']
|
||||
|
||||
### Opis modułów
|
||||
* type - typ potrawy: wegańska lub z mięsem
|
||||
* appetite - apetyt gościa, świadczy o tym jak duża potrawa spełni jego oczekiwania,
|
||||
np. duże danie będzie inne dla osób o dużym i małym apetycie
|
||||
* size - rozmiar dania
|
||||
* money - zawartość portfela gościa, czyli na jak dużo może sobie pozwolić
|
||||
* name - etykieta potrawy, dopasowana w taki sposób by spełnić powyższe wymagania
|
||||
|
||||
|
||||
## Opis modułów
|
||||
|
||||
W pliku *utility* znajdują się podręczne funkcje użytkowe wykorzystywane przez pozostałe moduły programu.
|
||||
|
||||
@ -97,7 +86,7 @@ Generuje zbiór danych testowych o zadanej wielkości i zapisuje go w pliku o po
|
||||
|
||||
Działa na takiej samej zasadzie jak jej poprzedniczka. Z tym wyjątkiem, że generuje pojedynczy przykład.
|
||||
|
||||
Klasa *Question* reprezentuje pytanie, które służy do podziału danych w wierzchołkach decyzyjnych drzewa. Jej atrybuty oznajczają kolejno: etykiete kolumny zbioru danych, indeks wspomnianej kolumny oraz wartość, której dotyczy pytanie.
|
||||
Klasa *Question* reprezentuje pytanie, które służy do podziału danych w wierzchołkach decyzyjnych drzewa. Jej atrybuty oznajczają kolejno: etykiete kolumny zbioru danych, indeks wspomnianej kolumny oraz wartość, której dotyczyy pytanie.
|
||||
|
||||
class Question:
|
||||
def __init__(self, columnLabel, column, value):
|
||||
@ -112,7 +101,7 @@ Klasa *Question* reprezentuje pytanie, które służy do podziału danych w wier
|
||||
else:
|
||||
return val == self.value
|
||||
|
||||
Metoda match wskazuje jak na pytanie odpowiada zadany przykład.
|
||||
Metoda match decyduje jak na pytanie odpowiada zadany przykład.
|
||||
|
||||
Jądro algorytmu znajduje się w klasie *suggestionTree* w pilku *suggestionDecisionTree*. Metoda *readTrainingData* służy do odczytania zbioru uczącego z pliku *trainingData.csv* i zwrócenia przechowywanych w nim danych wraz z ich etykietami.
|
||||
|
||||
@ -193,7 +182,7 @@ Metoda *findBestSplit* znajduje pytanie, które w danej chwili spowoduje jak naj
|
||||
|
||||
return bestGain, bestQuestion
|
||||
|
||||
Klasa *Leaf* jest reprezentacją liścia drzewa czyli najbardziej zewnętrznego wierzchołka. W atrybucie *predictions* przechowuje oszacowanie etykiet/y, które może przyjąć przykład, który do niego trafi. Metoda *printLeaf* służy do eleganckiego wyświetlania oszacowania.
|
||||
Klasa *Leaf* jest reprezentacją liścia drzewa czyli najbardziej zewnętrznego wierzchołka. W atrybucie *predictions* przechowuje oszacowanie etykiet/y, które może przyjąć przykład, który doń trafi. Metoda *printLeaf* służy do eleganckiego wyświetlania oszacowania.
|
||||
|
||||
class Leaf:
|
||||
def __init__(self, rows):
|
||||
@ -261,52 +250,33 @@ Metoda *printTree* wyświetla strukturę drzewa w postaci tekstu w wierszu polec
|
||||
|
||||
Metoda *classify* przyporządkowuje danemu przykładowi odpowiadającą mu etykiete w drzewie.
|
||||
|
||||
### Działanie
|
||||
## Działanie
|
||||
|
||||
Drzewo jest budowane na podstawie zbioru uczącego. Algorytm podejmuje decyzje o tym jak podzielić zbiór na podstawie przyrostu informacji wynikającego z potencjalnego podziału. Przerywa działanie gdy przyrost wynosi *0*, co oznacza, że dotarł do liścia drzewa i dalszy podział nie jest możliwy. Kończąc swoje działanie zwraca korzeń klasy *DecisionNode*, który zawiera w atrybutach potomków> Umożliwia to rekurencyjne schodzenie po drzewie, które jest realizowane przez metodę *classify*.
|
||||
Drzewo jest budowane na podstawie zbioru uczącego. Algorytm podejmuje decyzje o tym jak podzielić zbiór na podstawie przyrostu informacji wynikającego z potencjalnego podziału. Przerywa działanie gdy przyrost wynosi *0*, co oznacza, że dotarł do liścia drzewa i podział nie jest możliwy. Kończąc swoje działanie zwraca korzeń klasy *DecisionNode*, który zawiera w atrybutach potomków co umożliwia rekurencyjne schodzenie po drzewie.
|
||||
|
||||
### Integracja z projektem
|
||||
|
||||
Deklaracja oraz inicjalizacja korzenia drzewa:
|
||||
|
||||
suggestionTreeRoot = SuggestionTree.buildTree(trainingData)
|
||||
|
||||
W projekcie można sprawdzić działanie podprojektu poprzez wciśnięcie, któregoś z klawiszy:
|
||||
|
||||
* 0 - sprawdzenie poprawności algorytmu na losowo wygenerowanym zbiorze testowym.
|
||||
|
||||
generateTestData('testData.csv', 100)
|
||||
testData = []
|
||||
with open('src/SubprojectMarcinDobrowolski/Data/testData.csv') as csv_file:
|
||||
csvReader = csv.reader(csv_file, delimiter=',')
|
||||
lineCount = 0
|
||||
for row in csvReader:
|
||||
example = []
|
||||
for column in row:
|
||||
if column.isdigit():
|
||||
example.append(int(column))
|
||||
else:
|
||||
example.append(column)
|
||||
if lineCount > 0:
|
||||
testData.append(example)
|
||||
lineCount += 1
|
||||
|
||||
print('Processed lines: ', lineCount)
|
||||
|
||||
print('Test examples predictions:')
|
||||
for example in testData:
|
||||
print('{} - {}'.format(example, SuggestionTree.classify(
|
||||
example, suggestionTreeRoot).printLeaf()))
|
||||
W projekcie można je wykorzystać poprzez wciśnięcie, któregoś z klawiszy:
|
||||
|
||||
* 0 - sprawdzenie poprawności algorytmu na losowo wygenerowanym zbiorze testowym. =
|
||||
* 1 - sprawdzenie poprawności algorytmu na losowo wygenerowanym przykładzie.
|
||||
|
||||
example = generateTestExample()
|
||||
print('Test example prediction: ')
|
||||
print('{} - {}'.format(example, SuggestionTree.classify(
|
||||
example, suggestionTreeRoot).printLeaf()))
|
||||
|
||||
* 2 - wyświetlenie struktury drzewa
|
||||
|
||||
SuggestionTree.printTree(suggestionTreeRoot)
|
||||
|
||||
Rezultaty zostają wypisane w konsoli.
|
||||
|
||||
```
|
||||
module: pygames
|
||||
Python: 3.7.7
|
||||
```
|
||||
|
||||
macOS / Linux
|
||||
|
||||
```
|
||||
pygames
|
||||
python main.py
|
||||
```
|
||||
|
||||
Windows
|
||||
|
||||
```
|
||||
pygames
|
||||
python main.py
|
||||
```
|
||||
|
196
path
196
path
@ -1,101 +1,101 @@
|
||||
type,size,money,appetite
|
||||
meat,regular,40,46
|
||||
meat,regular,38,15
|
||||
meat,regular,35,50
|
||||
meat,little,42,25
|
||||
meat,regular,29,34
|
||||
meat,little,38,47
|
||||
meat,regular,33,34
|
||||
meat,regular,54,29
|
||||
meat,regular,47,44
|
||||
meat,regular,27,15
|
||||
meat,regular,32,13
|
||||
meat,little,53,39
|
||||
meat,little,40,44
|
||||
meat,regular,25,39
|
||||
meat,regular,50,52
|
||||
meat,regular,29,20
|
||||
meat,little,58,31
|
||||
meat,regular,36,45
|
||||
meat,regular,59,20
|
||||
meat,regular,54,48
|
||||
meat,regular,25,32
|
||||
meat,regular,36,23
|
||||
meat,regular,57,29
|
||||
meat,little,13,54
|
||||
meat,little,43,52
|
||||
meat,little,58,24
|
||||
meat,little,30,35
|
||||
meat,little,24,33
|
||||
meat,regular,24,30
|
||||
meat,regular,41,48
|
||||
meat,regular,35,37
|
||||
meat,little,36,11
|
||||
meat,regular,22,24
|
||||
meat,regular,58,14
|
||||
meat,little,34,29
|
||||
meat,little,30,38
|
||||
meat,regular,54,45
|
||||
meat,regular,31,43
|
||||
meat,little,58,46
|
||||
meat,little,48,38
|
||||
meat,regular,44,44
|
||||
meat,regular,51,49
|
||||
meat,little,53,34
|
||||
meat,regular,51,48
|
||||
meat,regular,46,35
|
||||
meat,little,32,22
|
||||
meat,little,14,37
|
||||
meat,little,14,37
|
||||
meat,little,46,13
|
||||
meat,regular,40,16
|
||||
meat,regular,40,49
|
||||
meat,little,47,40
|
||||
meat,little,56,48
|
||||
meat,little,53,11
|
||||
meat,regular,45,25
|
||||
meat,little,17,34
|
||||
meat,regular,39,41
|
||||
meat,little,31,30
|
||||
meat,little,14,14
|
||||
meat,regular,38,38
|
||||
meat,regular,51,28
|
||||
meat,little,58,22
|
||||
meat,little,35,17
|
||||
meat,regular,47,36
|
||||
meat,little,55,20
|
||||
meat,regular,36,10
|
||||
meat,regular,53,22
|
||||
meat,regular,23,33
|
||||
meat,regular,27,29
|
||||
meat,regular,49,32
|
||||
meat,regular,36,15
|
||||
meat,regular,59,25
|
||||
meat,little,17,43
|
||||
meat,regular,39,49
|
||||
meat,little,35,33
|
||||
meat,little,10,32
|
||||
meat,little,11,49
|
||||
meat,regular,53,15
|
||||
meat,regular,29,13
|
||||
meat,little,12,14
|
||||
meat,little,27,31
|
||||
meat,regular,31,21
|
||||
meat,regular,58,13
|
||||
meat,little,46,19
|
||||
meat,little,11,27
|
||||
meat,regular,44,28
|
||||
meat,regular,40,14
|
||||
meat,little,57,24
|
||||
meat,regular,38,52
|
||||
meat,little,37,31
|
||||
meat,regular,34,15
|
||||
meat,little,41,25
|
||||
meat,regular,30,22
|
||||
meat,little,58,15
|
||||
meat,regular,22,12
|
||||
meat,little,46,44
|
||||
meat,regular,47,11
|
||||
meat,little,52,30
|
||||
meat,little,49,24
|
||||
meat,little,28,30
|
||||
meat,regular,27,19
|
||||
meat,regular,51,43
|
||||
meat,little,59,10
|
||||
meat,regular,38,44
|
||||
meat,regular,30,37
|
||||
meat,little,44,24
|
||||
meat,regular,34,45
|
||||
meat,regular,50,49
|
||||
meat,regular,36,50
|
||||
meat,little,13,22
|
||||
meat,little,28,25
|
||||
meat,regular,29,14
|
||||
meat,regular,56,17
|
||||
meat,regular,31,45
|
||||
meat,regular,57,42
|
||||
meat,regular,44,30
|
||||
meat,regular,33,45
|
||||
meat,little,52,25
|
||||
meat,little,48,15
|
||||
meat,regular,44,53
|
||||
meat,little,30,28
|
||||
meat,little,39,23
|
||||
meat,little,52,28
|
||||
meat,little,16,17
|
||||
meat,little,22,54
|
||||
meat,little,51,50
|
||||
meat,regular,51,25
|
||||
meat,little,14,28
|
||||
meat,little,51,25
|
||||
meat,regular,26,27
|
||||
meat,regular,26,35
|
||||
meat,little,41,24
|
||||
meat,regular,22,38
|
||||
meat,regular,37,25
|
||||
meat,regular,41,28
|
||||
meat,little,54,12
|
||||
meat,regular,31,22
|
||||
meat,regular,38,17
|
||||
meat,little,51,32
|
||||
meat,little,20,54
|
||||
meat,little,36,30
|
||||
meat,regular,33,46
|
||||
meat,little,43,16
|
||||
meat,regular,30,10
|
||||
meat,little,14,36
|
||||
meat,little,51,24
|
||||
meat,little,11,13
|
||||
meat,little,53,54
|
||||
meat,regular,27,12
|
||||
meat,regular,41,30
|
||||
meat,little,13,25
|
||||
meat,little,34,43
|
||||
meat,regular,51,45
|
||||
meat,regular,39,37
|
||||
meat,little,44,54
|
||||
meat,regular,37,12
|
||||
meat,regular,46,13
|
||||
meat,regular,25,21
|
||||
meat,regular,37,13
|
||||
meat,little,45,32
|
||||
meat,little,28,46
|
||||
meat,little,11,22
|
||||
meat,little,37,32
|
||||
meat,little,26,20
|
||||
meat,regular,21,35
|
||||
meat,regular,40,18
|
||||
meat,regular,59,42
|
||||
meat,regular,36,42
|
||||
meat,regular,57,16
|
||||
meat,little,20,47
|
||||
meat,little,18,34
|
||||
meat,regular,23,30
|
||||
meat,regular,44,23
|
||||
meat,little,41,28
|
||||
meat,little,12,49
|
||||
meat,regular,33,10
|
||||
meat,regular,44,21
|
||||
meat,little,57,51
|
||||
meat,regular,49,45
|
||||
meat,regular,36,40
|
||||
meat,little,24,11
|
||||
meat,little,45,45
|
||||
meat,little,59,30
|
||||
meat,little,16,23
|
||||
meat,little,57,13
|
||||
meat,little,58,36
|
||||
meat,little,35,16
|
||||
meat,little,44,54
|
||||
meat,regular,21,21
|
||||
meat,little,57,31
|
||||
meat,little,50,34
|
||||
meat,regular,25,40
|
||||
meat,regular,57,45
|
||||
meat,little,28,22
|
||||
meat,regular,41,53
|
||||
meat,little,10,19
|
||||
meat,little,32,53
|
||||
meat,little,29,22
|
||||
|
Loading…
Reference in New Issue
Block a user