import numpy as np import gui.imld_gui_window as igw class Model(): # method: Model::constructor # # arguments: # algo: the algorithm chosen # win_input: GUI input display # win_output: GUI output display # win_log: GUI process log # # return: none # def __init__(self, algo, win_input, win_output, win_log): # copy the inputs into class data # self.input_d = win_input self.output_d = win_output self.log_d = win_log self.algo = algo self.step_index = 0 # method: model::step # # arguments: # None # # return: none # # This method goes through each step of the algorithmic process def step(self): # step 1 training the data # if self.step_index == 1: if self.input_d.canvas.axes.collections is not None: self.input_d.clear_result_plot() if self.output_d.canvas.axes.collections == len(self.output_d.class_info): self.output_d.clear_result_plot() self.train() # plotting the decision surface # elif self.step_index == 2: self.plot_decision_surface() # classifying the eval data and computing the errors # elif self.step_index == 4: self.classify_eval() pass # displaying the errors on the process log # elif self.step_index == 3: self.compute_errors(self.input_d) self.display_errors("Training") pass # method: Model::is_done # # arguments: # None # # return: none # # This method checks whether the model has finished def is_done(self): if self.step_index > 4: finished = True else: finished = False return finished # method: Model::increment_step # # arguments: # None # # return: none # # This method sets the model to the next step of the algorithm def increment_step(self): self.step_index += 1 # method: Model::reset_step # # arguments: # None # # return: none # # This method resets the model's process def reset_step(self): self.log_d.append("Process Resetting...") self.step_index = 0 # method: Model::train # # arguments: # None # # return: none # # This method runs the algorithm def train(self): self.algo.run_algo() # method: Model::plot_decision_surface # # arguments: # None # # return: none # # This method plots the decision surface based on the algo's prediction def plot_decision_surface(self): xx, yy, Z = self.algo.predict(self.algo.input_d, self.algo.data) self.decision_surface(self.input_d, xx, yy, Z) # method: Model::compute_errors # # arguments: # g_data: data from GUI's graph # # return: none # # This method computes the errors of the algorithm def compute_errors(self, g_data): # verify the number of classes used # self.samples = 0 classes = len(g_data.class_info) incorrect = [0] * classes # get the data for i in range(classes): data = np.array(g_data.canvas.axes.collections[i].get_offsets()) size = data.shape[0] self.samples = self.samples + size predicted = [0] * classes expected = g_data.canvas.axes.collections[i].get_gid()[0] # check prediction matches expectations # for j in range(size): prediction = self.algo.prediction_classifier(data[j]) if prediction != expected[j]: predicted[prediction] = predicted[prediction] + 1 incorrect[i] = incorrect[i] + 1 else: predicted[prediction] = predicted[prediction] + 1 # calculate total errors self.total_error = sum(incorrect) self.error = (self.total_error/self.samples) * 100 # method: Model::classify_eval # # arguments: # None # # return: none # # This method classifies the evaluation data def classify_eval(self): # find total classes plotted # #num_classes = self.output_d.canvas.axes.collections # total number of classes initialized #Look here temporary hot fix out_num_classes = len(self.output_d.canvas.axes.collections) in_num_classes = len(self.input_d.class_info) # check if plots and classes in dictionary match # if out_num_classes == 0: self.log_d.append("There's no Eval Data to classify.\n") return False elif in_num_classes != out_num_classes: self.log_d.append("Eval and Training data classes do not match") else: # calculate and print errors # self.compute_errors(self.output_d) self.display_errors("Evaluation") # extract data # self.algo.extract_data(self.output_d) # run algorithm # xx, yy, Z = self.algo.predict(self.algo.output_d, self.algo.data) # plot decision surface # self.decision_surface(self.output_d, xx, yy, Z) # method: Model::display_errors # # arguments: # None # # return: none # # This method displays the errors calculated def display_errors(self, data): text = "\n{} Error Rate = {} / {} = {:.2f}%\n".format(data, self.total_error, self.samples, self.error) self.log_d.append(text) # method: Model::decision_surface # # arguments: # ax: the axes that the decision surface is graphed upon # xx: the x coordinate data # yy: the y coordinate data # Z: the height values of the contour # # return: none # # This method computes the errors of the algorithm def decision_surface(self, ax, xx, yy, Z): Z = Z.reshape(xx.shape) ax.canvas.axes.contourf(xx, yy, Z, alpha=0.4, cmap = self.input_d.surface_color) ax.canvas.draw_idle() # # end of class # # end of file