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