예제 #1
0
파일: Vista.py 프로젝트: berrio97/TFG_NBA
class Vista(Frame):
    # Inicializa el controlador y algunas variables globales
    # Params:
    #   master: instancia de Window
    #   modelo: Modelo
    def __init__(self, master, modelo):
        Frame.__init__(self, master)
        self.pack()
        self.master = master
        self.modelo = modelo
        self.controlador = Controlador(self.modelo, self)
        self.col1 = 'khaki1'
        self.col2 = 'snow'
        self.font = 'Helvetica'
        self.init_components()
        return

    #Inicializa los componentes de la Vista y los coloca
    def init_components(self):
        self.label_model = Label(self.master,
                                 text='Modelo',
                                 font=(self.font, 14),
                                 relief=GROOVE,
                                 bg=self.col2)
        self.label_data = Label(self.master,
                                text='Datos',
                                font=(self.font, 14),
                                relief=GROOVE,
                                bg=self.col2)
        self.label_pred = Label(self.master,
                                text='Predicción',
                                font=(self.font, 14),
                                relief=GROOVE,
                                bg=self.col2)
        self.label_res = Label(self.master,
                               text='Resultados',
                               font=(self.font, 14),
                               relief=GROOVE,
                               bg=self.col2)

        self.variable = StringVar()
        self.variable.set('Modelo 1')
        self.variable.trace("w", self.change_model)

        self.model_selector = OptionMenu(self.master, self.variable,
                                         *list(self.modelo.modelos.keys()))

        self.frame = Frame(self.master)

        self.alg_label = Label(self.frame,
                               text='Algoritmo',
                               font=(self.font, 8, 'bold'),
                               bg=self.col2,
                               relief='raised',
                               width=20)
        self.seas_label = Label(self.frame,
                                text='Temporadas',
                                font=(self.font, 8, 'bold'),
                                bg=self.col2,
                                relief='raised',
                                width=20)
        self.columns_label = Label(self.frame,
                                   text='Selección columnas',
                                   font=(self.font, 8, 'bold'),
                                   bg=self.col2,
                                   relief='raised',
                                   width=20)
        self.pca_label = Label(self.frame,
                               text='PCA',
                               font=(self.font, 8, 'bold'),
                               bg=self.col2,
                               relief='raised',
                               width=20)
        self.params_label = Label(self.frame,
                                  text='Parámetros',
                                  bg=self.col2,
                                  font=(self.font, 8, 'bold'),
                                  relief='raised',
                                  width=20)

        self.alg_value = Label(self.frame,
                               text='',
                               font=(self.font, 8),
                               bg=self.col2,
                               relief='raised',
                               width=30)
        self.seas_value = Label(self.frame,
                                text='',
                                font=(self.font, 8),
                                bg=self.col2,
                                relief='raised',
                                width=30)
        self.columns_value = Label(self.frame,
                                   text='',
                                   font=(self.font, 8),
                                   bg=self.col2,
                                   relief='raised',
                                   width=30)
        self.pca_value = Label(self.frame,
                               text='',
                               font=(self.font, 8),
                               bg=self.col2,
                               relief='raised',
                               width=30)
        self.params_value = Label(self.frame,
                                  text='',
                                  font=(self.font, 8),
                                  bg=self.col2,
                                  relief='raised',
                                  width=30)

        self.load_model_but = Button(self.master,
                                     text='Cargar modelo',
                                     state='disabled',
                                     command=self.load_model,
                                     bg=self.col2)

        self.train_model_but = Button(self.master,
                                      text='Entrenar modelo',
                                      state='disabled',
                                      command=self.train_model,
                                      bg=self.col2)

        self.load_data_but = Button(self.master,
                                    text='Cargar datos',
                                    command=self.load_data,
                                    bg=self.col2)

        self.ref_but = Button(self.master,
                              text='Actualizar datos',
                              command=self.refresh,
                              bg=self.col2)

        self.home_label = Label(self.master, text='Equipo local', bg=self.col1)
        self.away_label = Label(self.master,
                                text='Equipo visitante',
                                bg=self.col1)

        self.home = StringVar()
        self.home.set(self.modelo.teams[0])
        self.homeOptionMenu = OptionMenu(self.master, self.home,
                                         *list(self.modelo.teams))
        self.homeOptionMenu.config(state='disabled')

        self.away = StringVar()
        self.away.set(self.modelo.teams[0])
        self.awayOptionMenu = OptionMenu(self.master, self.away,
                                         *list(self.modelo.teams))
        self.awayOptionMenu.config(state='disabled')

        self.calendar = Calendar(self.master, state='disabled')

        self.pred_but = Button(self.master,
                               text='Hallar predicciones',
                               state='disabled',
                               command=self.exec_prediction,
                               bg=self.col2)

        self.result = Label(self.master,
                            text='',
                            bg=self.col1,
                            font=(self.font, 10, 'bold'))
        self.pred = Label(self.master,
                          text='',
                          bg=self.col1,
                          font=(self.font, 10, 'bold'))
        self.team_win = Label(self.master,
                              text='',
                              bg=self.col1,
                              font=(self.font, 10, 'bold'))

        self.sep1 = Separator(self.master, orient=HORIZONTAL)
        self.sep2 = Separator(self.master, orient=HORIZONTAL)
        self.sep3 = Separator(self.master, orient=VERTICAL)

        self.label_error = Label(self.master,
                                 text='',
                                 font=('device', 10),
                                 fg='red',
                                 bg=self.col1)

        ### PACKING & PLACING
        self.label_model.pack()
        self.label_model.place(relx=0.05, rely=0.05, anchor=W)
        self.label_data.pack()
        self.label_data.place(relx=0.05, rely=0.4, anchor=W)
        self.label_pred.pack()
        self.label_pred.place(relx=0.05, rely=0.6, anchor=W)

        self.model_selector.pack()
        self.model_selector.place(relx=0.15, rely=0.15, anchor=CENTER)

        self.frame.pack()
        self.frame.place(relx=0.25, rely=0.05)

        self.alg_label.grid(row=0, rowspan=1, column=0, columnspan=1)
        self.seas_label.grid(row=1, rowspan=1, column=0, columnspan=1)
        self.columns_label.grid(row=2, rowspan=1, column=0, columnspan=1)
        self.pca_label.grid(row=3, rowspan=1, column=0, columnspan=1)
        self.params_label.grid(row=4,
                               rowspan=1,
                               column=0,
                               columnspan=1,
                               sticky=N + E + S + W)

        self.alg_value.grid(row=0, rowspan=1, column=1, columnspan=1)
        self.seas_value.grid(row=1, rowspan=1, column=1, columnspan=1)
        self.columns_value.grid(row=2, rowspan=1, column=1, columnspan=1)
        self.pca_value.grid(row=3, rowspan=1, column=1, columnspan=1)
        self.params_value.grid(row=4, rowspan=1, column=1, columnspan=1)
        self.change_model()

        self.load_model_but.pack()
        self.load_model_but.place(relx=0.1, rely=0.48, anchor=CENTER)

        self.train_model_but.pack()
        self.train_model_but.place(relx=0.24, rely=0.48, anchor=CENTER)

        self.load_data_but.pack()
        self.load_data_but.place(relx=0.38, rely=0.48, anchor=CENTER)

        self.ref_but.pack()
        self.ref_but.place(relx=0.52, rely=0.48, anchor=CENTER)

        self.home_label.pack()
        self.home_label.place(relx=0.1, rely=0.7, anchor=CENTER)

        self.away_label.pack()
        self.away_label.place(relx=0.25, rely=0.7, anchor=CENTER)

        self.homeOptionMenu.pack()
        self.homeOptionMenu.place(relx=0.1, rely=0.75, anchor=CENTER)

        self.awayOptionMenu.pack()
        self.awayOptionMenu.place(relx=0.25, rely=0.75, anchor=CENTER)

        self.calendar.pack()
        self.calendar.place(relx=0.45, rely=0.75, anchor=CENTER)

        self.pred_but.pack()
        self.pred_but.place(relx=0.17, rely=0.82, anchor=CENTER)

        self.label_res.pack()
        self.label_res.place(relx=0.7, rely=0.05, anchor=CENTER)

        self.result.pack()
        self.result.place(relx=0.8, rely=0.15, anchor=CENTER)

        self.pred.pack()
        self.pred.place(relx=0.8, rely=0.85, anchor=CENTER)

        self.team_win.pack()
        self.team_win.place(relx=0.8, rely=0.89, anchor=CENTER)

        self.sep1.place(relx=0.05, rely=0.33, relwidth=0.55)
        self.sep2.place(relx=0.05, rely=0.53, relwidth=0.55)
        self.sep3.place(relx=0.61, rely=0.05, relheight=0.9)

        self.label_error.place(relx=0.8, rely=0.93, anchor=CENTER)

    # Evento de cambiar el modelo que se esta seleccionando
    def change_model(self, *args):
        self.controlador.evento_change_model()
        if self.modelo.model_read is not None:
            self.alg_value['text'] = self.modelo.algorithms[
                self.modelo.model_read.alg]
            if self.modelo.model_read.seasons == '2015':
                seas = 'Desde 2014/2015'
            elif self.modelo.model_read.seasons == '2005':
                seas = 'Desde 2004/2005'
            else:
                seas = 'Desde 2000/2001'
            self.seas_value['text'] = seas
            self.columns_value['text'] = self.modelo.model_read.col
            self.pca_value[
                'text'] = 'Sí' if self.modelo.model_read.pca_analysis else 'No'

            if not pd.isnull(self.modelo.model_read.params):
                aux = ''
                for key in list(eval(self.modelo.model_read.params).keys()):
                    aux += str(key) + ': ' + str(
                        eval(self.modelo.model_read.params)[key]) + '\n'
                self.params_value['text'] = aux[:-1]
            else:
                self.params_value['text'] = ''

    # Evento de cargar los datos de los partidos
    def load_data(self):
        self.controlador.evento_load()
        if self.modelo.file is not None:
            self.load_model_but['state'] = 'active'
            self.calendar['state'] = 'normal'
            self.label_error.config(fg='green')
            self.label_error['text'] = 'Datos cargados con éxito'

    # Evento de actualizar los datos
    def refresh(self):
        self.controlador.evento_refresh()
        self.load_data()
        self.label_error.config(fg='green')
        self.label_error['text'] = 'Datos actualizados con éxito'

    # Evento de cargar el modelo predictivo seleccionado
    def load_model(self):
        self.label_error['text'] = ''
        self.train_model_but['state'] = 'active'
        self.controlador.evento_load_model()
        performance = self.modelo.modelo_prediccion.ac
        self.result['text'] = 'TASA DE ACIERTO: ' + str(
            performance.round(4) * 100) + '%'
        self.roc()
        self.pred_but['state'] = 'active'
        self.homeOptionMenu.config(state='active')
        self.awayOptionMenu.config(state='active')
        self.label_error.config(fg='green')
        self.label_error['text'] = 'Modelo cargado con éxito'

    # Evento de entrenar el modelo predictivo seleccionado
    def train_model(self):
        self.label_error['text'] = ''
        self.controlador.evento_train_model()
        self.load_model()

    # Evento de crear una curva ROC sobre los resultados del modelo predictivo seleccionado
    def roc(self):
        fpr, tpr, thres = roc_curve(self.modelo.modelo_prediccion.Y_test,
                                    self.modelo.modelo_prediccion.scores)
        auc_roc = auc(fpr, tpr)

        fig = Figure(figsize=(3.2, 3.2))
        a = fig.add_subplot(111)
        a.plot(fpr, tpr, color='blue', label='AUC %0.2f' % auc_roc)
        a.legend(loc="lower right")

        a.set_position([0.15, 0.12, 0.8, 0.8])
        a.set_xticks(ticks=np.arange(0, 1.5, 0.5))
        a.set_yticks(ticks=np.arange(0, 1.5, 0.5))
        a.set_xticklabels(labels=np.arange(0, 1.5, 0.5),
                          fontdict={'fontsize': 8})
        a.set_yticklabels(labels=np.arange(0, 1.5, 0.5),
                          fontdict={'fontsize': 8})
        a.set_title("Curva ROC " +
                    self.modelo.algorithms[self.modelo.model_read.alg],
                    fontsize=10)
        a.set_ylabel("TPR", fontsize=8)
        a.set_xlabel("FPR", fontsize=8)

        canvas = FigureCanvasTkAgg(fig, master=self.master)
        canvas.get_tk_widget().pack(expand=True)
        canvas.get_tk_widget().place(relx=0.8, rely=0.5, anchor=CENTER)
        canvas.draw()

    # Evento de crear las predicciones para un partido determinado
    def exec_prediction(self):
        date = datetime.strptime(self.calendar.get_date(), '%m/%d/%y')
        game_id = str(
            date.year
        ) + '%02d' % date.month + '%02d' % date.day + '0' + self.home.get()

        if self.home.get() != self.away.get() and self.home.get(
        ) != 'No seleccionado' and self.away.get() != 'No seleccionado':
            aux = self.modelo.modelo_prediccion.predictions_test
            game_true = game_id in aux.game_id.values
            if date < datetime.today() and game_true and aux[
                    aux.game_id == game_id]['a_team_id'].values[
                        0] == self.away.get() or date > datetime.today():
                self.controlador.evento_exec_prediction()
                predres = self.modelo.prediction
                aux = self.home.get() if predres else self.away.get()
                self.label_error['text'] = ''
                self.pred['text'] = str(self.home.get()) + ': ' + str(
                    predres.round(2)) + '\t' + str(
                        self.away.get()) + ': ' + str((1 - predres).round(2))
                if date < datetime.today():
                    self.team_win['text'] = 'Victoria real: ' + str(aux)
            else:
                self.label_error.config(fg='red')
                self.label_error[
                    'text'] = 'ERROR: Ese partido no se ha disputado.'
                self.pred['text'] = ''
                self.team_win['text'] = ''
        elif self.home.get() == 'No seleccionado' and self.away.get(
        ) == 'No seleccionado':
            self.label_error.config(fg='red')
            self.pred['text'] = ''
            self.team_win['text'] = ''
            self.label_error['text'] = 'ERROR: Hay que determinar los equipos'
        elif self.home.get() == 'No seleccionado' or self.away.get(
        ) == 'No seleccionado':
            self.label_error.config(fg='red')
            self.pred['text'] = ''
            self.team_win['text'] = ''
            self.label_error['text'] = 'ERROR: Falta un equipo por determinar'
        elif self.home.get() == self.away.get():
            self.label_error.config(fg='red')
            self.pred['text'] = ''
            self.team_win['text'] = ''
            self.label_error[
                'text'] = 'ERROR: Los equipos deben ser diferentes.'