diff --git a/.idea/misc.xml b/.idea/misc.xml index adaa126..715ed69 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/.idea/wozek.iml b/.idea/wozek.iml index 904114b..a9742fc 100644 --- a/.idea/wozek.iml +++ b/.idea/wozek.iml @@ -4,7 +4,7 @@ - + diff --git a/Archiwum/README.md b/Raporty/README.md similarity index 100% rename from Archiwum/README.md rename to Raporty/README.md diff --git a/Raport_444420.md b/Raporty/Raport_444420.md similarity index 100% rename from Raport_444420.md rename to Raporty/Raport_444420.md diff --git a/Archiwum/environment.md b/Raporty/environment.md similarity index 100% rename from Archiwum/environment.md rename to Raporty/environment.md diff --git a/Raporty/raport_444428.md b/Raporty/raport_444428.md new file mode 100644 index 0000000..f99651d --- /dev/null +++ b/Raporty/raport_444428.md @@ -0,0 +1,132 @@ +# Wojciech Lukasik - drzewa decyzyjne, algorytm CART + +### Opis podprojektu +Podprojekt implementuje tworzenie drzewa decyzyjnego w oparciu o algorytm CART +(Classification And Regression Tree), które pomaga Agentowi w rozpoznaniu słodyczy na podstawie +ich cech fizycznych (kolor, kształt, masa, rozmiar). + +Wszystkie funkcje oraz klasy wykorzystywane w tym podprojekcie znajdują się w pliku decision_tree.py, +dane uczące znajdują się w pliku data.py w liście learning_data + +### Tworzenie drzewa decyzyjnego + +Główną funkcją jest build_tree(rows), która jak wskazuje nazwa tworzy drzewo. Funkcja przyjmuje +jako argument listę zawierającą zestaw danych, w tym przypadku będą to słodycze o różnych właściwościach. + +```python +def build_tree(rows): + gain, question = find_best_split(rows) + + if gain == 0: + return Leaf(rows) + + true_rows, false_rows = partition(rows, question) + + true_branch = build_tree(true_rows) + + false_branch = build_tree(false_rows) + + return DecisionNode(question, true_branch, false_branch) +``` + +Drzewo jest budowane w oparciu o najlepsze możlwe podziały (najbardziej korzystne 'pytanie', które można zadać). +Zajmuje się tym funkcja + +`find_best_split(rows)` która dla wszystkich właściwości przekazanego zestawu informacji +wylicza dla nich 'zysk informacji'. + +Jeżeli nie otrzymujemy żadnych informacji (gain == 0) to znaczy, że znajdujemy +się w liściu drzewa. + +```python +def find_best_split(rows): + """ znajdź najlepsze możliwe pytanie do zadania, sprawdzając wszystkie + właściwośći oraz licząc dla nich 'info_gain' """ + best_gain = 0 + best_question = None + current_uncertainty = gini(rows) + n_features = len(rows[0]) - 1 + + for col in range(n_features): + values = set([row[col] for row in rows]) + + for val in values: + question = Question(col, val) + + true_rows, false_rows = partition(rows, question) + + if len(true_rows) == 0 or len(false_rows) == 0: + continue + + gain = info_gain(true_rows, false_rows, current_uncertainty) + + if gain > best_gain: + best_gain, best_question = gain, question + + return best_gain, best_question +``` + +Zysk informacji z danego podziału otrzymujemy obliczając wartość 'Gini Impurity'. Jest to miara tego jak często losowo +wybrany element zbioru byłby źle skategoryzowany, gdyby przypisać mu losową kategorię spośród wszystkich kategorii +znajdujących się w danym zbiorze. + +```python +def gini(rows): + counts = class_counts(rows) + impurity = 1 + for lbl in counts: + prob_of_lbl = counts[lbl] / float(len(rows)) + impurity -= prob_of_lbl ** 2 + return impurity +``` +`class_counts(rows)` to funkcja, która dla danego zestawu danych zwraca wszystkie unikalne klasy oraz liczbę ich wystąpień. + +Dla przykładu, dla zestawu w którym wszystkie elementy podchodzą pod tę samą kategorię wartość Gini będzie równa zero, +natomiast dla zbioru w którym znajdują się dwie kategorie wartość ta wyniesie 0,5. + +Po znalezieniu najbardziej optymalnego pytania, algorytm dzieli zestaw na elementy, dla których pytanie jest prawdziwe +(true_rows), oraz te dla których jest fałszywe (false_rows). Następnie wykonuje rekurencyjnie procedurę build_tree dla +obu poddrzew tak długo aż nie dojdzie do liści. + +Element o zadanym zestawie cech, zostaje odnaleziony w drzewie dzięki prostej procedurze + +`classify(row, node)` 'row' to lista cech elementu, natomiast 'node' na początu jest korzeniem już zbudowanego drzewa. + +Element jest odnaleziony dzięki +rekurencyjnym porównaniom atrybutów elementu z pytaniami w kolejnych węzłach drzewa. + +```python +def classify(row, node): + if isinstance(node, Leaf): + return node.predicions + + if node.question.match(row): + return classify(row, node.true_branch) + else: + return classify(row, node.false_branch) +``` + +### Zestaw uczący + +Zestaw budujący drzewo to lista zawierająca 27 przykładowych słodyczy. Ich atrybuty zapisane są w formacie ['kolor', +'kształt', 'masa', 'wielkość', 'nazwa']. Oczywiście przy wyszukiwaniu elementu w drzewie jego nazwa nie jest potrzebna +ponieważ to jej szukamy. Przykładowe elementy z zestawu uczącego: + +```python + ['black', 'rectangle', 51, 'small', 'Mars'], + ['gold', 'pack', 100, 'big', 'Haribo'], + ['purple', 'rectangle', 100, 'big', 'Milka'], + ['brown', 'pack', 45, 'small', 'M&M'], +``` + +### Implementacja w projekcie + +Przy rozpoczęciu głównej pętli programu w pliku `main.py` drzewo `my_tree` zostaje zbudowane w oparciu o dane +`data.learning_data`. + +Gdy program już działa, po wciśnięciu `spacji` jeden ze słodyczy zostanie losowo wybrany z zestawu `data.learning_data` +oraz umieszczony na polu `board[9][0]`, a jego nazwa zostanie wypisana w konsoli. Następnie Agent przemieszcza się do +punktu `board[9][0]` i rozpoczne procedurę wyszukiwania elementu w zbudowanym drzewie. Na końcu wypisze w +konsoli nazwę produktu. + + diff --git a/route-planning.md b/Raporty/route-planning.md similarity index 100% rename from route-planning.md rename to Raporty/route-planning.md diff --git a/__pycache__/mcda.cpython-37.pyc b/__pycache__/mcda.cpython-37.pyc new file mode 100644 index 0000000..a51297a Binary files /dev/null and b/__pycache__/mcda.cpython-37.pyc differ diff --git a/__pycache__/product.cpython-37.pyc b/__pycache__/product.cpython-37.pyc new file mode 100644 index 0000000..c5d2555 Binary files /dev/null and b/__pycache__/product.cpython-37.pyc differ diff --git a/__pycache__/supply.cpython-37.pyc b/__pycache__/supply.cpython-37.pyc new file mode 100644 index 0000000..fb3c123 Binary files /dev/null and b/__pycache__/supply.cpython-37.pyc differ