Path: blob/main/Trabajo_grupal/WG4/Grupo_1.py
2714 views
# -*- coding: utf-8 -*-12#%% Grupo 1. Miembros del grupo:34# 20163197, Enrique Alfonso Pazos5# 20191894, Ilenia Ttito6# 20151595, Rodrigo Ramos7# 20193469, Luis Egusquiza8# 20163377, Jean Niño de Guzmán910#%%11import os12import pyreadr13import pandas as pd14import numpy as np15import scipy.stats as stats16from scipy.stats import t1718user = os.getlogin() # Usuario del dispositivo19os.chdir(f"C:/Users/{user}/Documentos/GitHub/1ECO35_2022_2/data") # Definimos el directorio2021# Leemos el archivo de Workspace R22dr = pyreadr.read_r("../data/cps2012.Rdata")2324# Convertimos en un dataframe25dr = dr['data']262728#Filtando la base de datos29# Saca la varianza de cada vector y lo pasa a un array30var_cols = dr.var().to_numpy()3132# Se filtran las columnas con valores constantes (muchos 1), nos aseguramos de tener variables continuas3334df = dr.iloc[:,np.where(var_cols != 0)[0]]35X = df.iloc[:,1:10] # Filtra por posiciones36y = df[['lnw']] # Filtra por el nombre de la variable3738#%% Parte 13940class RegClass( object ):4142#Se definen X como un data frame y Y como una serie, y se indica que en este caso si habrá intercepto43def __init__( self, X : pd.DataFrame , y : pd.Series , intercept = True ):4445#Creación de atributos de acuerdo a la base de datos (añadiendo intercepto)46self.X = X47self.y = y48self.intercept = intercept4950#Se indica que se apliquen las funciones si se cuenta con intercepto, y en caso contrario no hacer nada51if self.intercept:5253self.X[ 'Intercept' ] = 154#Coloación del Intercepto como la primera columna55cols = self.X.columns.tolist() # nombre de varaible a lista56new_cols_orders = [cols[ -1 ]] + cols[ 0:-1 ] # Se juntan las listas57self.X = self.X.loc[ : , new_cols_orders ] # usamos .loc que filtra por nombre de filas o columnas5859else:60pass6162# Creación de nuevos atributos6364self.X_np = self.X.values # Dataframe a multi array65self.y_np = y.values.reshape( -1 , 1 ) # de objeto serie a array columna66self.columns = self.X.columns.tolist() # nombre de la base de datos como objeto lista6768def reg_beta_OLS( self ):6970#Se llaman a los atributos antes creados para el cálculos de los betas con a matriz X y la columna y71X_np = self.X_np72y_np = self.y_np737475#Estimación de los Betas76beta_ols = np.linalg.inv( X_np.T @ X_np ) @ ( X_np.T @ y_np )7778#Se llama al atributos de las columnas antes creado para hacer un dataframe con los betas estimados79index_names = self.columns8081#Se crea un dataframe con los betas estimados de cada variable en la columna y82beta_OLS_output = pd.DataFrame( beta_ols , index = index_names , columns = [ 'Coef.' ] )8384#Se pone el vector de coeficientes estimados como un atributo85self.beta_OLS = beta_OLS_output8687return beta_OLS_output8889#%% Parte 29091def reg_var_OLS( self ):92#Se llaman a los betas calculados anteriormente93self.reg_beta_OLS()9495#Se crean nuevos valores y atributos para el calculos de la varianza96X_np = self.X_np97y_np = self.y_np9899100# Se traen los valores estimados de los betas101beta_OLS = self.beta_OLS.values.reshape( - 1, 1 )102103# Calculos de los errores104e = y_np - ( X_np @ beta_OLS )#############################################################105106# creo el atributo error porque me servirá más adelante107self.error = e ################################################################108109# Calculo de la varianza de los errores.110N = X_np.shape[ 0 ]111112total_parameters = X_np.shape[ 1 ]113error_var = ( (e.T @ e)[ 0 ] )/( N - total_parameters )114115# Se calculan las varianzas y covarianzas116var_OLS = error_var * np.linalg.inv( X_np.T @ X_np )117118#Se trae el atributo de columnas antes creado para añadirlo al nuevo dataframe119index_names = self.columns120121#Se coloca en un dataframe las varianzas de todas las variables así y su respectiva covarianza122var_OLS_output = pd.DataFrame( var_OLS , index = index_names , columns = index_names )123124#Se pone la matriz de varianzas y covarianza como un atributo con los valores en el dataframe calculado antes125self.var_OLS = var_OLS_output126127return var_OLS128129def reg_OLS( self ):130131# Se llaman los betas y varianzas estimados anteriormente132self.reg_beta_OLS()133self.reg_var_OLS()134135#Se llama a un atributo antes creado de X136X = self.X_np137138#Se traen los valores antes calculados en los dos métodos anteriores (Betas y Varianza)139beta_OLS = self.beta_OLS.values.reshape( -1, 1 )140var_OLS = self.var_OLS.values141142#Creación de los errores estándar143beta_se = np.sqrt( np.diag( var_OLS ) )144145# Se calcula el test statistic para cada coeficiente para poder calcular los intervalos de confianza146t_stat = beta_OLS.ravel() / beta_se.ravel()147148#Creación del p-value para creación de intervalos de confianza149N = X.shape[ 0 ]150k = beta_OLS.size151pvalue = (1 - t.cdf(t_stat, df= N - k) ) * 2152# defining index names153index_names = self.columns154155156# Creación de los intervalos de confianza de acuerdo a los betas estimados157158int1 = beta_OLS.ravel() + 1.96*beta_se159int2 = beta_OLS.ravel() - 1.96*beta_se160161table_data ={ 'Coef.' : beta_OLS.ravel() ,162"Std.Err." : beta_se.ravel(),163"t" : t_stat.ravel(),164"P>|t|" : pvalue.ravel(),165"[0.025" : int1.ravel(),166"0.975]" : int2.ravel()167}168169# defining a pandas dataframe170reg_OLS = pd.DataFrame( table_data , index = index_names )171172return reg_OLS173174#%% Parte 3175176177def pregunta_3_var_covar_robust( self ):178179X = self.X_np180181"""182De manera más fácil sería llamar al error como atributo calculado en la función anterior183"""184# Necesito el atributo error (e)185self.reg_var_OLS186e = self.error187188# Número de observaciones = N189N = X.shape[ 0 ]190191# Matriz Varianza-Covarianza robusta: (X'X)^-1 * X' * Matriz_White * X * (X'X)^-1192193# Matriz propuesta por White: error^2 * M.Identidad(MxM)194# Para crearla, primero debo crear una matriz de paso: e x e'195Matriz_de_paso = e @ e.T196197# En caso de que hubiera 4 observaciones:198# e1^2 e1e2 e1e3 e1e4199# e2e1 e2^2 e2e3 e2e4200# e3e1 e3e2 e3^2 e3e4201# e4e1 e4e2 e4e3 e4^2202203# Ahora, debo diagonalizarla:204205lista = np.arange(N)206for i in lista:207for j in lista:208if(i == j):209Matriz_de_paso[i][j] = Matriz_de_paso[i][j]210else:211Matriz_de_paso[i][j] = 0212213# De esa manera, obtendría la matriz de White214# e1^2 0 0 0215# 0 e2^2 0 0216# 0 0 e3^2 0217# 0 0 0 e4^2218Matriz_White = Matriz_de_paso219220# Ahora, calcularé la matriz robusta:221# Primero, (X'X)^-1222Inversa = np.linalg.inv( X.T @ X )223224# (X'X)^-1 * X' * Matriz_White * X * (X'X)^-1225var_OLS_robusta = Inversa @ X.T @ Matriz_White @ X @ Inversa226227# Crearé un atributo con el valor de la matriz var-covar robusta.228self.var_robust = var_OLS_robusta229230# Nombres de las columnas231index_names = self.columns232233var_robusta = pd.DataFrame(var_OLS_robusta , index = index_names , columns = index_names )234235#return var_robusta236return var_robusta237238def pregunta_3_parte_2( self ):239240# Los atributos de las funciones anteriores241self.reg_beta_OLS()242self.pregunta_3_var_covar_robust243244# X tomará el valor del atributo X_np245X = self.X_np246247# La variable beta_OLS tomará los valores del output anterior transformado, aqui, a vector fila.248beta_OLS = self.beta_OLS.values.reshape( -1, 1 )249250# La variable var_robust será igual al output de la función anterior251var_robust = self.var_robust252253"""254OJO: voy a calcular la desviación estándar con la matriz de var-covar robusta:255"""256257# Desviación estándar de los coeficientes estimados: (var(beta^))^0.5258beta_desv_std = np.sqrt( np.diag( var_robust ) )259260N = X.shape[ 0 ] # Número de observaciones261k = X.shape[ 1 ] # Número de regresores262263# Intervalos de confianza:264265# t_tabla -> Distribución T-Student al 95% de confianza.266# bound = Desv. Estandar*t_tabla267bound = beta_desv_std * stats.t.ppf( ( 1 + 0.95 ) / 2., N - k )268269# Límite superior = Coeficiente + Desv. Estandar*t_stat270lim_sup_robust = beta_OLS.ravel() + bound271272# Límite superior = Coeficiente - Desv. Estandar*t_stat273lim_inf_robust = beta_OLS.ravel() - bound274275276tabla = { 'desv. std. robusto' : beta_desv_std.ravel(),277'límite superior robusto' : lim_sup_robust.ravel(),278'límite inferior robusto' : lim_inf_robust.ravel()}279280# defining index names281index_names = self.columns282283resultados_robustos = pd.DataFrame(tabla, index = index_names )284285return resultados_robustos286287#%% Parte 4288289def rmse(self):290291self.reg_beta_OLS()292293#Se crean nuevos valores y atributos para el calculos de la varianza294X_np = self.X_np295y_np = self.y_np296297# Se traen los valores estimados de los betas298beta_OLS = self.beta_OLS.values.reshape( - 1, 1 )299300# Calculos de los errores301e = y_np - ( X_np @ beta_OLS )302303suma = 0304305for v in self.y_np:306suma = suma + v307308media = suma/len(self.y_np)309310#columna = self.y_np311312columna = np.ones(len(self.y_np))313314y_dif= self.y_np - media * columna.T315316sct = y_dif.T @ y_dif317318sce = e.T @ e319320R_2 = 1- (sce / sct)321self.R_cuadrado = R_2322323root = pow(sct/len(self.y_np), 0.5)324self.root_mse = root325326327R_2_root = {'R^2': R_2.ravel(),328'Root' :root.ravel()}329330index_names = self.columns331resultados = pd.DataFrame(R_2_root, index = index_names )332333return resultados334335336#%% Parte 5337338def mostrar_resultados (self):339340#Corremos las funciones pertinentes341self.reg_OLS()342self.pregunta_3_var_covar_robust()343self.pregunta_3_parte_2()344self.rmse()345346# Generamos los resultados de los coeficientes estimados, errores estándar e intervalos de confianza, el R2 y el RMSE347result_df ={ 'Coef.' : self.beta_OLS.flatten(),348'desv. std. robusto' : self.beta_desv_std.flatten(),349'límite superior robusto' : self.lim_sup_robust.flatten(),350'límite inferior robusto' : self.lim_inf_robust.flatten()351}352# defining index names353index_names = self.columns354355# Definimos estos dentro de un dataframe356OLS_results = pd.DataFrame( result_df , index = index_names )357return OLS_results358359# Creamos un diccionario que muestra todos los resultados360361final_results ={"OLS": OLS_results , "R_2" : self.R_cuadrado.flatten() ,362"Root-MSE" : self.R_2_root.flatten()}363364return final_results365366