From 948842ad760dc128920b1083d3ef9bd23fe9123a Mon Sep 17 00:00:00 2001 From: Aleksandra Werda Date: Wed, 3 Jun 2020 01:58:24 +0000 Subject: [PATCH] s444391/SzIProjekt --- Aleksandra Werda - drzewa decyzyje.md | 127 ++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 Aleksandra Werda - drzewa decyzyje.md diff --git a/Aleksandra Werda - drzewa decyzyje.md b/Aleksandra Werda - drzewa decyzyje.md new file mode 100644 index 0000000..736a97b --- /dev/null +++ b/Aleksandra Werda - drzewa decyzyje.md @@ -0,0 +1,127 @@ +# *Sztuczna inteligencja - projekt zespołowy - Autonomiczny Traktor* + +##### autorzy: Aleksandra Werda, Natalia Wiśniewska, Kinga Jagodzińska, Aleksandra Jonas +*** +## Aleksandra Werda - podprojekt: Sprawdzanie stanu gleby przy użyciu drzewa decyzyjnego +___ +### **Zbiór uczący:** +Zbiorem uczącym jest podany odgórnie zestaw danych w tablicy tablic *lista*, w którym kolejno każda cyfra odpowiada za: liczbę chwastów, poziom podlania, ph oraz ogólny stan gleby. +``` +lista = [[1, 6, 7, 'neutralny'], + [5, 8, 6, 'neutralny'], + [5, 1, 7, 'zły'], + [5, 5, 7, 'neutralny'], + [1, 6, 6, 'neutralny'], + [2, 8, 7, 'dobry'], ... ] +``` + +___ +### **Tworzenie drzewa:** +Algorytm tworzymy w pętli while. Tworzymy listę *open_set* aby wiedzieć jakie wierzchołki diagramu mamy jeszcze odwiedzić, a także *closed_set*, aby łatwo rozpoznać te już odwiedzone. Definiujemy także *ob1* i *ob2*, które są dwoma wierzchołkami do których przejdziemy po zadaniu pytania w wierzchołku x. Mamy też listę node która mówi nam w jakim wierzchołku obecnie znajduje się przykład z tablicy *lista* o danym indeksie. Tablica myset podaje nam indeksy przykładów, które obecnie znajdują się w wierzchołku x. Pętlą for szukamy wersji pytania, która podzieli myset na dwie części o jak najmniejszym zanieczyszczeniu. +``` +for y in itertools.product(range(3), range(1, 11)): + self.Questions(y[0], y[1]) + s1 = [0, 0, 0] + s2 = [0, 0, 0] + ``` +W funkcji for korzystamy z funkcji **Questions**, używając jako danych wejściowych kombinacji dwóch liczb: pierwsza wskazuje na to na który parametr z listy bedziemy patrzeć; druga mówi nam o liczbie, która podzieli myset według tego czy dany przykład posiada parametr wynoszący mniej czy więcej niż ta liczba. +``` +def Questions(self, column, number): + for i in self.myset: + if lista[i][column] <= number: + self.node[i] = self.ob1 + else: + self.node[i] = self.ob2 +``` +Następnie liczymy ile w każdej z tych grup jest przykładów, w których występuje jeden z konkretnych stanów gleby. +``` + for z in range(len(lista)): + if self.node[z] == self.ob1: + if lista[z][3] == "zły": + s1[0] = s1[0] + 1 + elif lista[z][3] == "neutralny": + s1[1] = s1[1] + 1 + elif lista[z][3] == "dobry": + s1[2] = s1[2] + 1 + elif self.node[z] == self.ob2: + if lista[z][3] == "zły": + s2[0] = s2[0] + 1 + elif lista[z][3] == "neutralny": + s2[1] = s2[1] + 1 + elif lista[z][3] == "dobry": + s2[2] = s2[2] + 1 +s1_suma = s1[0] + s1[1] + s1[2] +s2_suma = s2[0] + s2[1] + s2[2] +``` +Szukamy kombinacji z najniższym zanieczyszczeniem, wywołując przy tym dla wierzchołków *ob1* i *ob2* funkcję **Gini**, która sprawdza "czystość", czyli jak często losowy element będzie źle zindentyfikowany. +``` +if s1_suma > 0 and s2_suma > 0: + impurity = s1_suma / (s1_suma + s2_suma) * self.Gini(s1, s1_suma) + s2_suma / (s1_suma + s2_suma) * self.Gini(s2, s2_suma) + if imp > impurity: + imp = impurity # imp = najmniejsze imp jakie uzyskalismy + opt = y # y = optymalna kombincja (48) + l_gini = self.Gini(s1, s1_suma) + p_gini = self.Gini(s2, s2_suma) + odp_s1 = s1 + odp_s2 = s2 +``` +``` +def Gini(self, x, suma): + return 1 - (x[0] / suma) ** 2 - (x[1] / suma) + ** 2 - (x[2] / suma) ** 2 +``` +Jeżeli nasz lewy bądź prawy wierzchołek jest równy 0, oznacza to, że jest "czysty", czyli został prawidłowo oznaczony(jednym z 3 możliwych stanów). +``` +if l_gini != 0: + open_node.append(self.ob1) +else: + for y in range(3): + if odp_s1[y] != 0: + odp = y + self.odpowiedzi.append([self.ob1, odp]) +if p_gini != 0: + open_node.append(self.ob2) +else: + for y in range(3): + if odp_s2[y] != 0: + odp = y + self.odpowiedzi.append([self.ob2, odp]) + +``` + +W funkcji **Solutions** generujemy listę wszystkich wierzchołków, które znajdują się na liście odpowiedzi. +``` +for i in range(len(self.odpowiedzi)): + lista_wierzch_kończących.append(self.odpowiedzi[i][0]) +``` +Jeżeli wierzchołek w którym jesteśmy znajduje się w tablicy odpowiedzi, to zapamiętujemy go. Następnie porównujemy przypisane wartości z konkretnymi cyframi, które określają stan naszej gleby. W tym wypadku 0 - *zły*, 1 - *neutralny*, 2- *dobry*. W efekcie dostajemy informację zwrotną w jakim stanie jest nasza gleba. +``` +if x in lista_wierzch_kończących: + for i in range(len(self.odpowiedzi)): + if self.odpowiedzi[i][0] == x: + self.ind = i + break +``` +Jeśli natomiast nasz wiechołek nie jest liściem w zbudowanym przez nas w funkcji **Algorithm** drzewie, wtedy szukamy wierzchołka do którego przejdziemy na podstawie pytania wpisanego w wierzchołek x na podstawie tablicy pytania. + +``` +for i in range(len(self.pytania)): + if self.pytania[i][0] == x: + self.ind = i + break +x = self.Answers(self.pytania[self.ind][1][0], +self.pytania[self.ind][1][1], pole) +``` +Używamy do tego funkcji **Answers**: +``` +def Answers(self, a, b, pole): + if pole[a] <= b: + return self.pytania[self.ind][2][0] + else: + return self.pytania[self.ind][2][1] +``` + + + + +