3.0 KiB
Sztuczna inteligencja - projekt zespołowy - Autonomiczny Traktor
autorzy: Aleksandra Werda, Natalia Wiśniewska, Kinga Jagodzińska, Aleksandra Jonas
Natalia Wiśniewska - podprojekt: drzewa decyzyjne
Celem podprojektu jest ustalenie czy traktor powinien podlać dane pole. Wykorzystałam do tego drzewa decyzyjne w oparciu o algorytm CART.
Zbiór uczący
Zbiorem uczącym jest tablica, która składa się z 25 przykładów w których dane kolejno to:
- informacja o tym czy gleba jest sucha lub nawodniona
- ile dni temu ostatnio podlewano pole
- co ile dni należy podlewać dane pole
- czy ma tego dnia padać
- kiedy ostatnio padało.
training_data = [
['n', 2, 3, 't', 1],
['s', 1, 3, 't', 1],
['s', 5, 2, 'n', 1],
['n', 3, 5, 'n', 1],
Tworzenie drzewa
Na samym początku program sprawdza czy odpowiednia wartość w danym przykładzie to liczba czy też litera.
def is_numeric(value):
return isinstance(value, int) or isinstance(value, float)
Dzięki temu w klasie Question ustalamy w jaki sposób porównujemy ze sobą dane oraz budujemy takie pytanie.
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
def __repr__(self):
condition = "=="
if is_numeric(self.value):
condition = ">="
return "Czy %s %s %s?" % (
header[self.column], condition, str(self.value))
Funkcja partition tworzy kolejne gałęzie poprzez podział odpowiedzi na fałszywe i prawdziwe.
Następnie obliczamy wartość gini oraz przyrost informacji:
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)
Dzięki temu program ile informacji uzyska po podziale na podzbiory i może zadecydować, o które dane powinien zapytać.
Na sam koniec tworzymy nasze 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 Decision_Node(question, true_branch, false_branch)
Zawiera ono najbardziej opłacalne pytanie w korzeniu, a następnie dzieli drzewo na dwa podrzewa- takie, w którym odpowiedzią na pierwsze pytanie była prawda i takie, w którym był to fałsz. Następnie w tych węzłach program zadaje kolejne pytania tak jak w korzeniu. Odpowiedzi na ostatnie pytania nazywamy liśćmi. Na ich podstawie ustalamy czy pole należy podlać czy nie.