Zaktualizuj 'Natalia_Wiśniewska_drzewa_decyzyjne.md'

This commit is contained in:
Natalia Wiśniewska 2020-06-03 16:49:10 +00:00
parent e426cb9e46
commit 59a0858ac4

View File

@ -1,78 +1,78 @@
# *Sztuczna inteligencja - projekt zespołowy - Autonomiczny Traktor* # *Sztuczna inteligencja - projekt zespołowy - Autonomiczny Traktor*
#### autorzy: Aleksandra Werda, Natalia Wiśniewska, Kinga Jagodzińska, Aleksandra Jonas #### autorzy: Aleksandra Werda, Natalia Wiśniewska, Kinga Jagodzińska, Aleksandra Jonas
*** ***
## Natalia Wiśniewska - podprojekt: drzewa decyzyjne ## 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. 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 ## 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: 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 - informacja o tym czy gleba jest sucha lub nawodniona
- ile dni temu ostatnio podlewano pole - ile dni temu ostatnio podlewano pole
- co ile dni należy podlewać dane pole - co ile dni należy podlewać dane pole
- czy ma tego dnia padać - czy ma tego dnia padać
- kiedy ostatnio padało. - kiedy ostatnio padało.
``` ```
training_data = [ training_data = [
['n', 2, 3, 't', 1], ['n', 2, 3, 't', 1],
['s', 1, 3, 't', 1], ['s', 1, 3, 't', 1],
['s', 5, 2, 'n', 1], ['s', 5, 2, 'n', 1],
['n', 3, 5, 'n', 1], ['n', 3, 5, 'n', 1],
``` ```
## Tworzenie drzewa ## Tworzenie drzewa
Na samym początku program sprawdza czy odpowiednia wartość w danym przykładzie to liczba czy też litera. Na samym początku program sprawdza czy odpowiednia wartość w danym przykładzie to liczba czy też litera.
``` ```
def is_numeric(value): def is_numeric(value):
return isinstance(value, int) or isinstance(value, float) 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. Dzięki temu w klasie **Question** ustalamy w jaki sposób porównujemy ze sobą dane oraz budujemy takie pytanie.
``` ```
class Question: class Question:
def __init__(self, column, value): def __init__(self, column, value):
self.column = column self.column = column
self.value = value self.value = value
def match(self, example): def match(self, example):
val = example[self.column] val = example[self.column]
if is_numeric(val): if is_numeric(val):
return val >= self.value return val >= self.value
else: else:
return val == self.value return val == self.value
def __repr__(self): def __repr__(self):
condition = "==" condition = "=="
if is_numeric(self.value): if is_numeric(self.value):
condition = ">=" condition = ">="
return "Czy %s %s %s?" % ( return "Czy %s %s %s?" % (
header[self.column], condition, str(self.value)) header[self.column], condition, str(self.value))
``` ```
Funkcja **partition** tworzy kolejne gałęzie poprzez podział odpowiedzi na fałszywe i prawdziwe. Funkcja **partition** tworzy kolejne gałęzie poprzez podział odpowiedzi na fałszywe i prawdziwe.
Następnie obliczamy wartość gini oraz przyrost informacji:
``` Następnie obliczamy wartość gini oraz przyrost informacji:
def gini(rows): ```
counts = class_counts(rows) def gini(rows):
impurity = 1 counts = class_counts(rows)
for lbl in counts: impurity = 1
prob_of_lbl = counts[lbl] / float(len(rows)) for lbl in counts:
impurity -= prob_of_lbl**2 prob_of_lbl = counts[lbl] / float(len(rows))
return impurity impurity -= prob_of_lbl**2
return impurity
def info_gain(left, right, current_uncertainty): def info_gain(left, right, current_uncertainty):
p = float(len(left)) / (len(left) + len(right)) p = float(len(left)) / (len(left) + len(right))
return current_uncertainty - p * gini(left) - (1 - p) * gini(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ć. 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: Na sam koniec tworzymy nasze drzewo:
``` ```
def build_tree(rows): def build_tree(rows):
gain, question = find_best_split(rows) gain, question = find_best_split(rows)
if gain == 0: if gain == 0:
return Leaf(rows) return Leaf(rows)
true_rows, false_rows = partition(rows, question) true_rows, false_rows = partition(rows, question)
true_branch = build_tree(true_rows) true_branch = build_tree(true_rows)
false_branch = build_tree(false_rows) false_branch = build_tree(false_rows)
return Decision_Node(question, true_branch, false_branch) 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. 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.