From 905a2d9c1e92065adf8250a7518943fac8fcfc42 Mon Sep 17 00:00:00 2001 From: Kamila Matysiak Date: Sun, 24 May 2020 20:14:49 +0000 Subject: [PATCH] Zaktualizuj 'decisiontree.md' --- decisiontree.md | 115 +++++++++++++++--------------------------------- 1 file changed, 36 insertions(+), 79 deletions(-) diff --git a/decisiontree.md b/decisiontree.md index 8f41e4f..6036691 100644 --- a/decisiontree.md +++ b/decisiontree.md @@ -2,77 +2,37 @@ **Członkowie zespołu:** Marcin Kwapisz, Kamila Matysiak, Piotr Rychlicki, Justyna Zarzycka -**Temat podprojektu:** Wybór trybu pracy traktora za pomocą drzewa decyzyjnego - **Autor podprojektu:** Kamila Matysiak ### Drzewo Decyzyjne -Projekt wykorzystuje drzewo decyzyjne do wybrania najoptymalniejszego trybu. Uruchamia się go za pomocą klawisza **F6**. +Projekt wykorzystuje drzewo decyzyjne do wybrania czynności dla każdego pola, a następnie wysłania traktora do pól zgodnych z obecnie wybranym trybem. -#### Przygotowanie Danych: +Projekt używa metody CART (Classification and Regression Tree). Tworzy on drzewo binarne, w którym rozpatruje wszystkie możliwe podziały zbioru wartości cech na dwa rozłączne i uzupełniające się podzbiory dla cech dyskretnych. -Za przygotowanie danych odpowiedzialne są dwie funkcje: -**find_best_action**, która pobiera macierz pól, tworzy macierz czynności do wykonania, a następnie buduje drzewo. +Uruchamia się go za pomocą klawisza **F6**. + +#### Zbiór uczący: + +Zbiorem uczącym jest zestaw danych informujących drzewo jak postępować z polem o danych parametrach. +Kolejne cyfry odpowiadają za: nawodnienie pola, obecność chwastów, czy pole jest puste, czy jest do zbioru. ``` - def find_best_action(self): - testing_data = [] - matrix = self.field.get_matrix() # pobranie macierzy pól - matrix_todo = [] - for i in range(10): - matrix_todo.append([]) - verse = matrix[i] - for j in range(len(verse)): - coord = (i, j) - current_field = check(verse[j]) # czynnosci ktore trzeba jeszcze zrobic na kazdym polu - matrix_todo[i].append([]) - for action in current_field: - matrix_todo[i][j].append(action[-1]) - testing_data.extend(current_field) - if len(testing_data) > 0: - x = build_tree(testing_data) # zbudowanie drzewa - print_tree(x) - if isinstance(x, Leaf): # wybór najlepszej czynności do wykonania - self.best_action = self.find_remaining_action(matrix_todo) - return - self.best_action = x.question.column - print(header[x.question.column]) - print(x.question.value) - else: - self.best_action = self.find_remaining_action(matrix_todo) - return - -``` -Drugą funkcją jest **check**, która interpretuje pola z macierzy na podstawie numerów, dodając stringa z czynnością do wykonania na danym polu. - -``` -def check(field): - if field == 0: - return [[0, 0, 1, 0, "Zasadzic"], [0, 0, 1, 0, "Podlac"]] - elif field == 1: - return [[0, 1, 1, 0, "Odchwascic"], [0, 1, 1, 0, "Podlac"], [0, 1, 1, 0, "Zasadzic"]] - elif field == 2: - return [[0, 0, 0, 0, "Podlac"]] - elif field == 3: - return [[0, 1, 0, 0, "Odchwascic"], [0, 1, 0, 0, "Podlac"]] - elif field == 4: - return [[1, 0, 1, 0, "Zasadzic"]] - elif field == 5: - return [[1, 1, 1, 0, "Odchwascic"], [1, 1, 1, 0, "Zasadzic"]] - elif field == 6: - return [] - elif field == 7: - return [[1, 1, 0, 0, "Odchwascic"]] - elif field == 8: - return [[0, 0, 0, 1, "Zebrac"], [0, 0, 0, 1, "Potem podlac"], [0, 0, 0, 1, "Potem zasadzic"]] - else: - print("Błąd: Zły numer pola.") - +training_data = [[0, 0, 1, 0, "Zasadzic"], + [0, 1, 1, 0, "Odchwascic"], + [0, 0, 0, 0, "Podlac"], + [0, 1, 0, 0, "Odchwascic"], + [1, 0, 1, 0, "Zasadzic"], + [1, 1, 1, 0, "Odchwascic"], + [1, 0, 0, 0, "Czekac"], + [1, 1, 0, 0, "Odchwascic"], + [0, 0, 0, 1, "Zebrac"]] + self.tree = build_tree(training_data) + print_tree(self.tree) ``` -#### Budowanie Drzewa: +#### Algotytm tworzenia drzewa: Budowanie drzewa zaczynamy od stworzenia klasy **Question**, w której będziemy tworzyć zapytanie, na podstawie którego będziemy dzielić nasze dane. Następnie tworzymy funkcję **partition**, która na podstawie zapytania dzieli nam dane na spełnione i niespełnione wiersze: @@ -88,9 +48,9 @@ def partition(rows, question): return true_rows, false_rows ``` -Następnie wyokrzystujemy **Index Gini** i **Info Gain**. - Index Gini mierzy jak często losowo wybrany element będzie źle zindentyfikowany. - Information gain mierzy zmianę entropii, która powstaje na skutek podziału zestawu danych testowych na mniejsze części. +Następnie wyokrzystujemy **Index Gini**, który mierzy jak często losowo wybrany element będzie źle zindentyfikowany. Gdy jest równy 0, oznacza to, że element zostanie właściwie oznaczony. + + ``` # funkcja implementująca indeks gini @@ -102,7 +62,6 @@ def gini(rows): impurity -= prob_of_lbl ** 2 return impurity -#information gain def info_gain(left, right, current_uncertainty): p = float(len(left)) / (len(left) + len(right)) return current_uncertainty - p * gini(left) - (1 - p) * gini(right) @@ -148,22 +107,20 @@ def build_tree(rows): #### Integracja: -Gdy za pomocą funkcji **find_best_action** zostanie wybrana najbardziej opłacalna czynność wykorzystujemy algorytm A* zaimplementowany w pliku **pathfinding.py**. Ustawiamy tryb traktora i w pętli każemy znajdować mu pola. +Program sczytuje dane z głównego projektu, następnie interpretuje je za pomocą prostej funkcji **translate**, która zwraca informacje o stanie pola. Następnie za pomocą drzewa określamy czynność, jaka powinna zostać wykonana na tym polu. Wykonanie pracy zlecamy klasie **pathfinding**, która za pomocą algorytmu A* wysyła traktor na pola odpowiadające wybranemu trybowi. ``` - def do_best_action(self): - self.traktor.set_mode(self.best_action) - while self.path.pathfinding(self.traktor, self.field, self.ui) != 0: - pass + def search_field(self): + matrix = self.field.get_matrix() + for i in range(len(matrix)): + for j in range(len(matrix[i])): + print("Pole (%d,%d) Przewidziania czynnosc: %s" + % (i, j, print_leaf(classify(translate(matrix[i][j]), self.tree)))) + if work[self.traktor.get_mode()] in self.work_field(classify(translate(matrix[i][j]), self.tree)): + print("Zgodna z aktualnym trybem, czynnosc wykonywana") + self.path.find_path(self.traktor, self.field, self.ui, [j, i]) + self.ui.update() + time.sleep(0.5) ``` -Kiedy zostanie już tylko jedna czynność do wykonania przypisujemy jej **find_remaining_action**, dzięki czemu nasze pole zostanie w pełni oprawione. -``` - def find_remaining_action(self, matrix_todo): - for row in matrix_todo: - for field in row: - for action in field: - print(action) - return work.index(action) - return -1 -``` \ No newline at end of file +