import time header = ["hydration", "weeds", "empty", "ready", "TODO"] work = ["Podlac", "Odchwascic", "Zasadzic", "Zebrac"] order = [3, 1, 2, 0] # ustalenie kolejnosci czynnosci # 3 - zebranie # 1 - odchwaszczenie # 2 - zasadzenie # 0 - podlanie def translate(field): if field == 0: return [0, 0, 1, 0] elif field == 1: return [0, 1, 1, 0] elif field == 2: return [0, 0, 0, 0] elif field == 3: return [0, 1, 0, 0] elif field == 4: return [1, 0, 1, 0] elif field == 5: return [1, 1, 1, 0] elif field == 6: return [1, 0, 0, 0] elif field == 7: return [1, 1, 0, 0] elif field == 8: return [0, 0, 0, 1] else: print("Błąd: Zły numer pola.") # 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 else: return val == self.value # wyświetlenie pytania def __repr__(self): if is_numeric(self.value): condition = "==" return "Czy %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 label in counts: prob_of_label = counts[label] / float(len(rows)) impurity -= prob_of_label ** 2 return impurity def info_gain(true, false, current_uncertainty): p = float(len(true)) / (len(true) + len(false)) return current_uncertainty - p * gini(true) - (1 - p) * gini(false) # 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) # funkcja wypisująca drzewo def print_tree(node, spacing=""): if isinstance(node, Leaf): print(spacing + "Przewidywana czynność:", node.predictions) return print(spacing + str(node.question)) print(spacing + '--> Prawda: ') print_tree(node.true_branch, spacing + " ") print(spacing + '--> Fałsz: ') print_tree(node.false_branch, spacing + " ") def classify(field, node): if isinstance(node, Leaf): return node.predictions if node.question.match(field): return classify(field, node.true_branch) else: return classify(field, node.false_branch) def print_leaf(counts): total = sum(counts.values()) * 1.0 probs = {} for label in counts.keys(): probs[label] = str(int(counts[label] / total * 100)) + "%" return probs class main(): def __init__(self, traktor, field, ui, path): self.traktor = traktor self.field = field self.ui = ui self.path = path self.best_action = 0 # tworzymy zbior uczacy, w ktorym podajemy wszystkie mozliwe pola i czynnosci 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) print("------------------") print("TEST:") # for i in range(len(training_data)): # print("Przewidziania czynnosc: %s Czynnosc: %s" # % (print_leaf(classify(translate(i), self.tree)), training_data[i][-1])) # if training_data[i][-1] in self.work_field(classify(translate(i), self.tree)): # continue # else: # print("Testowanie zakonczone niepowodzeniem") # break print("Przewidziania czynnosc: %s Czynnosc: Zasadzic" % print_leaf(classify(translate(4), self.tree))) print("Przewidziania czynnosc: %s Czynnosc: Odchwascic" % print_leaf(classify(translate(5), self.tree))) print("Przewidziania czynnosc: %s Czynnosc: Odchwascic" % print_leaf(classify(translate(7), self.tree))) def main(self): for action in order: self.traktor.set_mode(action) self.search_field() print("Koniec roboty") def work_field(self, labels): works = [] for label in labels: if labels[label] > 0: works.append(label) return works 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)