diff --git a/Kamila.py b/Kamila.py index 5cad369..6b7e2ac 100644 --- a/Kamila.py +++ b/Kamila.py @@ -1,9 +1,228 @@ +import pandas as pd +from sklearn.tree import DecisionTreeClassifier +from sklearn.model_selection import train_test_split +from sklearn import metrics +import numpy + +header = ["hydration", "weeds", "empty", "ready", "TODO"] +work = ["Podlac", "Odchwascic", "Zasadzic", "Zebrac"] + + +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("wrong field number") + + +# liczenie ilości prac do wykonania +def class_counts(rows): + counts = {} + for row in rows: + label = row[-1] + if label not in counts: + counts[label] = 0 + counts[label] += 1 + return counts + + +# sprawdzenie czy wartość jest liczbą +def is_numeric(value): + return isinstance(value, int) or isinstance(value, float) + + +# klasa tworząca zapytanie do podziału danych +class Question(): + def __init__(self, column, value): + self.column = column + self.value = value + + def match(self, example): + val = example[self.column] + if is_numeric(val): + return val == self.value + + # wyświetlenie pytania + def __repr__(self): + if is_numeric(self.value): + condition = "==" + return "Is %s %s %s?" % ( + header[self.column], condition, str(self.value) + ) + + +# podział danych na spełnione i niespełnione wiersze +def partition(rows, question): + true_rows, false_rows = [], [] + for row in rows: + if question.match(row): + true_rows.append(row) + else: + false_rows.append(row) + return true_rows, false_rows + + +# funkcja implementująca indeks gini +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 + + +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) + + +# znalezienie najlepszego "miejsca" na podział danych +def find_best_split(rows): + 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 + + +class Leaf: + def __init__(self, rows): + self.predictions = class_counts(rows) + + +class DecisionNode: + def __init__(self, question, true_branch, false_branch): + self.question = question + self.true_branch = true_branch + self.false_branch = false_branch + + +# funkcja budująca drzewo +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) + + +# funcka wypisująca drzewo +def print_tree(node, spacing=""): + if isinstance(node, Leaf): + print(spacing + "Predict", node.predictions) + return + + print(spacing + str(node.question)) + + print(spacing + '--> True: ') + print_tree(node.true_branch, spacing + " ") + + print(spacing + '--> False: ') + print_tree(node.false_branch, spacing + " ") + + class main(): - def __init__(self,traktor,field,ui,path): + def __init__(self, traktor, field, ui, path): self.traktor = traktor self.field = field self.ui = ui self.path = path + self.best_action = 0 def main(self): - pass \ No newline at end of file + # dane testowe + array = ([[8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + [7, 7, 7, 7, 7, 7, 7, 7, 7, 7], + [6, 6, 6, 6, 6, 6, 6, 6, 6, 6], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], + [2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) + + while (True): + self.find_best_action() + if self.best_action == -1: + break + self.do_best_action() + print("Koniec roboty") + + def find_best_action(self): + testing_data = [] + matrix = self.field.get_matrix() + matrix_todo = [] + # print(self.field) + 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) + # testing_data.append(current_field) + if len(testing_data) > 0: + x = build_tree(testing_data) + print_tree(x) + if isinstance(x, Leaf): + 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 + + 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 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 diff --git a/decisiontree.md b/decisiontree.md new file mode 100644 index 0000000..1835440 --- /dev/null +++ b/decisiontree.md @@ -0,0 +1,11 @@ +# Sztuczna Inteligencja - Raport + +**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 +