Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
robertopucp
GitHub Repository: robertopucp/1eco35_2022_2
Path: blob/main/Trabajo_grupal/WG4/Grupo_1.py
2714 views
1
# -*- coding: utf-8 -*-
2
3
#%% Grupo 1. Miembros del grupo:
4
5
# 20163197, Enrique Alfonso Pazos
6
# 20191894, Ilenia Ttito
7
# 20151595, Rodrigo Ramos
8
# 20193469, Luis Egusquiza
9
# 20163377, Jean Niño de Guzmán
10
11
#%%
12
import os
13
import pyreadr
14
import pandas as pd
15
import numpy as np
16
import scipy.stats as stats
17
from scipy.stats import t
18
19
user = os.getlogin() # Usuario del dispositivo
20
os.chdir(f"C:/Users/{user}/Documentos/GitHub/1ECO35_2022_2/data") # Definimos el directorio
21
22
# Leemos el archivo de Workspace R
23
dr = pyreadr.read_r("../data/cps2012.Rdata")
24
25
# Convertimos en un dataframe
26
dr = dr['data']
27
28
29
#Filtando la base de datos
30
# Saca la varianza de cada vector y lo pasa a un array
31
var_cols = dr.var().to_numpy()
32
33
# Se filtran las columnas con valores constantes (muchos 1), nos aseguramos de tener variables continuas
34
35
df = dr.iloc[:,np.where(var_cols != 0)[0]]
36
X = df.iloc[:,1:10] # Filtra por posiciones
37
y = df[['lnw']] # Filtra por el nombre de la variable
38
39
#%% Parte 1
40
41
class RegClass( object ):
42
43
#Se definen X como un data frame y Y como una serie, y se indica que en este caso si habrá intercepto
44
def __init__( self, X : pd.DataFrame , y : pd.Series , intercept = True ):
45
46
#Creación de atributos de acuerdo a la base de datos (añadiendo intercepto)
47
self.X = X
48
self.y = y
49
self.intercept = intercept
50
51
#Se indica que se apliquen las funciones si se cuenta con intercepto, y en caso contrario no hacer nada
52
if self.intercept:
53
54
self.X[ 'Intercept' ] = 1
55
#Coloación del Intercepto como la primera columna
56
cols = self.X.columns.tolist() # nombre de varaible a lista
57
new_cols_orders = [cols[ -1 ]] + cols[ 0:-1 ] # Se juntan las listas
58
self.X = self.X.loc[ : , new_cols_orders ] # usamos .loc que filtra por nombre de filas o columnas
59
60
else:
61
pass
62
63
# Creación de nuevos atributos
64
65
self.X_np = self.X.values # Dataframe a multi array
66
self.y_np = y.values.reshape( -1 , 1 ) # de objeto serie a array columna
67
self.columns = self.X.columns.tolist() # nombre de la base de datos como objeto lista
68
69
def reg_beta_OLS( self ):
70
71
#Se llaman a los atributos antes creados para el cálculos de los betas con a matriz X y la columna y
72
X_np = self.X_np
73
y_np = self.y_np
74
75
76
#Estimación de los Betas
77
beta_ols = np.linalg.inv( X_np.T @ X_np ) @ ( X_np.T @ y_np )
78
79
#Se llama al atributos de las columnas antes creado para hacer un dataframe con los betas estimados
80
index_names = self.columns
81
82
#Se crea un dataframe con los betas estimados de cada variable en la columna y
83
beta_OLS_output = pd.DataFrame( beta_ols , index = index_names , columns = [ 'Coef.' ] )
84
85
#Se pone el vector de coeficientes estimados como un atributo
86
self.beta_OLS = beta_OLS_output
87
88
return beta_OLS_output
89
90
#%% Parte 2
91
92
def reg_var_OLS( self ):
93
#Se llaman a los betas calculados anteriormente
94
self.reg_beta_OLS()
95
96
#Se crean nuevos valores y atributos para el calculos de la varianza
97
X_np = self.X_np
98
y_np = self.y_np
99
100
101
# Se traen los valores estimados de los betas
102
beta_OLS = self.beta_OLS.values.reshape( - 1, 1 )
103
104
# Calculos de los errores
105
e = y_np - ( X_np @ beta_OLS )#############################################################
106
107
# creo el atributo error porque me servirá más adelante
108
self.error = e ################################################################
109
110
# Calculo de la varianza de los errores.
111
N = X_np.shape[ 0 ]
112
113
total_parameters = X_np.shape[ 1 ]
114
error_var = ( (e.T @ e)[ 0 ] )/( N - total_parameters )
115
116
# Se calculan las varianzas y covarianzas
117
var_OLS = error_var * np.linalg.inv( X_np.T @ X_np )
118
119
#Se trae el atributo de columnas antes creado para añadirlo al nuevo dataframe
120
index_names = self.columns
121
122
#Se coloca en un dataframe las varianzas de todas las variables así y su respectiva covarianza
123
var_OLS_output = pd.DataFrame( var_OLS , index = index_names , columns = index_names )
124
125
#Se pone la matriz de varianzas y covarianza como un atributo con los valores en el dataframe calculado antes
126
self.var_OLS = var_OLS_output
127
128
return var_OLS
129
130
def reg_OLS( self ):
131
132
# Se llaman los betas y varianzas estimados anteriormente
133
self.reg_beta_OLS()
134
self.reg_var_OLS()
135
136
#Se llama a un atributo antes creado de X
137
X = self.X_np
138
139
#Se traen los valores antes calculados en los dos métodos anteriores (Betas y Varianza)
140
beta_OLS = self.beta_OLS.values.reshape( -1, 1 )
141
var_OLS = self.var_OLS.values
142
143
#Creación de los errores estándar
144
beta_se = np.sqrt( np.diag( var_OLS ) )
145
146
# Se calcula el test statistic para cada coeficiente para poder calcular los intervalos de confianza
147
t_stat = beta_OLS.ravel() / beta_se.ravel()
148
149
#Creación del p-value para creación de intervalos de confianza
150
N = X.shape[ 0 ]
151
k = beta_OLS.size
152
pvalue = (1 - t.cdf(t_stat, df= N - k) ) * 2
153
# defining index names
154
index_names = self.columns
155
156
157
# Creación de los intervalos de confianza de acuerdo a los betas estimados
158
159
int1 = beta_OLS.ravel() + 1.96*beta_se
160
int2 = beta_OLS.ravel() - 1.96*beta_se
161
162
table_data ={ 'Coef.' : beta_OLS.ravel() ,
163
"Std.Err." : beta_se.ravel(),
164
"t" : t_stat.ravel(),
165
"P>|t|" : pvalue.ravel(),
166
"[0.025" : int1.ravel(),
167
"0.975]" : int2.ravel()
168
}
169
170
# defining a pandas dataframe
171
reg_OLS = pd.DataFrame( table_data , index = index_names )
172
173
return reg_OLS
174
175
#%% Parte 3
176
177
178
def pregunta_3_var_covar_robust( self ):
179
180
X = self.X_np
181
182
"""
183
De manera más fácil sería llamar al error como atributo calculado en la función anterior
184
"""
185
# Necesito el atributo error (e)
186
self.reg_var_OLS
187
e = self.error
188
189
# Número de observaciones = N
190
N = X.shape[ 0 ]
191
192
# Matriz Varianza-Covarianza robusta: (X'X)^-1 * X' * Matriz_White * X * (X'X)^-1
193
194
# Matriz propuesta por White: error^2 * M.Identidad(MxM)
195
# Para crearla, primero debo crear una matriz de paso: e x e'
196
Matriz_de_paso = e @ e.T
197
198
# En caso de que hubiera 4 observaciones:
199
# e1^2 e1e2 e1e3 e1e4
200
# e2e1 e2^2 e2e3 e2e4
201
# e3e1 e3e2 e3^2 e3e4
202
# e4e1 e4e2 e4e3 e4^2
203
204
# Ahora, debo diagonalizarla:
205
206
lista = np.arange(N)
207
for i in lista:
208
for j in lista:
209
if(i == j):
210
Matriz_de_paso[i][j] = Matriz_de_paso[i][j]
211
else:
212
Matriz_de_paso[i][j] = 0
213
214
# De esa manera, obtendría la matriz de White
215
# e1^2 0 0 0
216
# 0 e2^2 0 0
217
# 0 0 e3^2 0
218
# 0 0 0 e4^2
219
Matriz_White = Matriz_de_paso
220
221
# Ahora, calcularé la matriz robusta:
222
# Primero, (X'X)^-1
223
Inversa = np.linalg.inv( X.T @ X )
224
225
# (X'X)^-1 * X' * Matriz_White * X * (X'X)^-1
226
var_OLS_robusta = Inversa @ X.T @ Matriz_White @ X @ Inversa
227
228
# Crearé un atributo con el valor de la matriz var-covar robusta.
229
self.var_robust = var_OLS_robusta
230
231
# Nombres de las columnas
232
index_names = self.columns
233
234
var_robusta = pd.DataFrame(var_OLS_robusta , index = index_names , columns = index_names )
235
236
#return var_robusta
237
return var_robusta
238
239
def pregunta_3_parte_2( self ):
240
241
# Los atributos de las funciones anteriores
242
self.reg_beta_OLS()
243
self.pregunta_3_var_covar_robust
244
245
# X tomará el valor del atributo X_np
246
X = self.X_np
247
248
# La variable beta_OLS tomará los valores del output anterior transformado, aqui, a vector fila.
249
beta_OLS = self.beta_OLS.values.reshape( -1, 1 )
250
251
# La variable var_robust será igual al output de la función anterior
252
var_robust = self.var_robust
253
254
"""
255
OJO: voy a calcular la desviación estándar con la matriz de var-covar robusta:
256
"""
257
258
# Desviación estándar de los coeficientes estimados: (var(beta^))^0.5
259
beta_desv_std = np.sqrt( np.diag( var_robust ) )
260
261
N = X.shape[ 0 ] # Número de observaciones
262
k = X.shape[ 1 ] # Número de regresores
263
264
# Intervalos de confianza:
265
266
# t_tabla -> Distribución T-Student al 95% de confianza.
267
# bound = Desv. Estandar*t_tabla
268
bound = beta_desv_std * stats.t.ppf( ( 1 + 0.95 ) / 2., N - k )
269
270
# Límite superior = Coeficiente + Desv. Estandar*t_stat
271
lim_sup_robust = beta_OLS.ravel() + bound
272
273
# Límite superior = Coeficiente - Desv. Estandar*t_stat
274
lim_inf_robust = beta_OLS.ravel() - bound
275
276
277
tabla = { 'desv. std. robusto' : beta_desv_std.ravel(),
278
'límite superior robusto' : lim_sup_robust.ravel(),
279
'límite inferior robusto' : lim_inf_robust.ravel()}
280
281
# defining index names
282
index_names = self.columns
283
284
resultados_robustos = pd.DataFrame(tabla, index = index_names )
285
286
return resultados_robustos
287
288
#%% Parte 4
289
290
def rmse(self):
291
292
self.reg_beta_OLS()
293
294
#Se crean nuevos valores y atributos para el calculos de la varianza
295
X_np = self.X_np
296
y_np = self.y_np
297
298
# Se traen los valores estimados de los betas
299
beta_OLS = self.beta_OLS.values.reshape( - 1, 1 )
300
301
# Calculos de los errores
302
e = y_np - ( X_np @ beta_OLS )
303
304
suma = 0
305
306
for v in self.y_np:
307
suma = suma + v
308
309
media = suma/len(self.y_np)
310
311
#columna = self.y_np
312
313
columna = np.ones(len(self.y_np))
314
315
y_dif= self.y_np - media * columna.T
316
317
sct = y_dif.T @ y_dif
318
319
sce = e.T @ e
320
321
R_2 = 1- (sce / sct)
322
self.R_cuadrado = R_2
323
324
root = pow(sct/len(self.y_np), 0.5)
325
self.root_mse = root
326
327
328
R_2_root = {'R^2': R_2.ravel(),
329
'Root' :root.ravel()}
330
331
index_names = self.columns
332
resultados = pd.DataFrame(R_2_root, index = index_names )
333
334
return resultados
335
336
337
#%% Parte 5
338
339
def mostrar_resultados (self):
340
341
#Corremos las funciones pertinentes
342
self.reg_OLS()
343
self.pregunta_3_var_covar_robust()
344
self.pregunta_3_parte_2()
345
self.rmse()
346
347
# Generamos los resultados de los coeficientes estimados, errores estándar e intervalos de confianza, el R2 y el RMSE
348
result_df ={ 'Coef.' : self.beta_OLS.flatten(),
349
'desv. std. robusto' : self.beta_desv_std.flatten(),
350
'límite superior robusto' : self.lim_sup_robust.flatten(),
351
'límite inferior robusto' : self.lim_inf_robust.flatten()
352
}
353
# defining index names
354
index_names = self.columns
355
356
# Definimos estos dentro de un dataframe
357
OLS_results = pd.DataFrame( result_df , index = index_names )
358
return OLS_results
359
360
# Creamos un diccionario que muestra todos los resultados
361
362
final_results ={"OLS": OLS_results , "R_2" : self.R_cuadrado.flatten() ,
363
"Root-MSE" : self.R_2_root.flatten()}
364
365
return final_results
366