import itertools from Training_list import lista class Tree(object): def __init__(self): self.node = [] for x in range(len(lista)): self.node.append(0) self.pytania = [] self.odpowiedzi = [] 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 # sprawdza "czystość" jak często losowo wybrany element będzie źle zindentyfikowany def Gini(self, x, suma): return 1 - (x[0] / suma) ** 2 - (x[1] / suma) ** 2 - (x[2] / suma) ** 2 def Algorithm(self): open_node = [0] #sprawdza jakie do jakich wierzchółków jeszcze musimy wejść closed_node = [] #aby sprawdzic w ktorych już byliśmy długość = 0 while open_node: # x to wierzchołek w którym obecnie jesteśmy for x in open_node: if x in closed_node: break self.ob1 = długość + 1 self.ob2 = długość + 2 długość += 2 self.myset = [] opt = [] imp = 1 for i in range(len(self.node)): if self.node[i] == x: self.myset.append(i) for y in itertools.product(range(3), range(1, 11)): self.Questions(y[0], y[1]) s1 = [0, 0, 0] s2 = [0, 0, 0] 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] if s1_suma > 0 and s2_suma > 0: # szukamy kombinacji z najniższym zanieczyszczeniem 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 # gini wskazuje na czystosc lewego i prawego wierzcholka l_gini = self.Gini(s1, s1_suma) p_gini = self.Gini(s2, s2_suma) odp_s1 = s1 odp_s2 = s2 self.pytania.append([x, opt, [self.ob1, self.ob2]]) self.Questions(opt[0], opt[1]) 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]) closed_node.append(x) if open_node == closed_node: break 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] #na podstawie drzewa podejmuje decyzje ktory ze stanów gleby przydzieli polu def Solution(self, pole): x = 0 lista_wierzch_kończących = [] # generujemy liste wszystkisch wierzch ktore sa w odpowiedzi for i in range(len(self.odpowiedzi)): lista_wierzch_kończących.append(self.odpowiedzi[i][0]) while True: 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 if self.odpowiedzi[self.ind][1] == 0: return("Gleba na polu jest w złym stanie. Wymaga natychmiastowej interwencji") elif self.odpowiedzi[self.ind][1] == 1: return("Gleba na polu jest w neutralnym stanie.") elif self.odpowiedzi[self.ind][1] == 2: return("Gleba na polu jest w dobrym stanie. Nie będzie wymagać interwencji przez jakiś czas.") break else: 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)