ANÁLISIS DE REGRESIÓN VARIACIÓN PRECIO

Maestría en Investivación Operativa y Estadística

UTP

Desarrollo de modelo de regresión lineal

Procesamiento de los datos

# Funciones

## Función para crear flextable
ftable <- function(x) {
  x %>% 
    flextable() %>% 
    theme_vanilla() %>%
    color(part = "footer", color = "#666666") %>%
    color( part = "header", color = "#FFFFFF") %>%
    bg( part = "header", bg = "#2c7fb8") %>%
    fontsize(size = 11) %>%
    font(fontname = 'Calibri') %>%
    # Ajustes de ancho y tipo de alineación de las columnas
    set_table_properties(layout = "autofit") %>% 
    # width(j=1, width = 3) %>%
    align(i = NULL, j = c(2:ncol(x)), align = "right", part = "all")
}
# Cargue y limpieza de datos.

dolar <- read.csv2("datasets/Tasa_de_Cambio_Representativa_del__Mercado_-Historico.csv") %>% 
  clean_names()
hass <- read.xlsx("datasets/Hass_Precios_Historicos.xlsx") %>% clean_names()
# Vamos a sacar un valor promedio de cada variable por mes
#Para el dolar vamos a tomar el campo vigenciadesde

dolar <- dolar %>% 
  mutate(fecha = as.Date(vigenciadesde, format = "%d/%m/%y")) %>% 
  mutate(mes = month(fecha), anio = year(fecha)) %>% 
  mutate(valor = as.double(str_replace(valor,",",""))) %>% 
  group_by(anio,mes) %>%
  summarise(precio_dolar = mean(valor), .groups = "drop") 
# 🖇️ Se genera el vector de meses para usarlo más abajo con la función match.
meses <- c("Enero", "Febrero", "Marzo", "Abril", "Mayo",
           "Junio", "Julio", "Agosto", "Septiembre", "Octubre",
           "Noviembre", "Diciembre")

hass <- hass %>% 
  # Otra forma de sacar el anio.
  #mutate(anio = substring(fecha,nchar(fecha)-4,nchar(fecha))) %>% 
  #mutate(espacio = grepl(", ",fecha))
  mutate(mes = sapply(strsplit(fecha, " "), "[", 2),
         anio = sapply(strsplit(fecha, " "), "[", 5)) %>% 
  mutate(anio = as.double(anio)) %>% 
  # 🖇 Se utiliza la función match con el vector meses.
  mutate(mes = match(mes,meses)) %>% 
  group_by(anio,mes) %>%
  summarise(precio_aguacate_kg = mean(precio_kg), .groups = "drop") 
hass 
## # A tibble: 134 × 3
##     anio   mes precio_aguacate_kg
##    <dbl> <int>              <dbl>
##  1  2012     6              3471 
##  2  2012     7              3460.
##  3  2012     8              3544.
##  4  2012     9              3792 
##  5  2012    10              3661.
##  6  2012    11              3580.
##  7  2012    12              2946 
##  8  2013     1              2776.
##  9  2013     2              2732.
## 10  2013     3              3313.
## # ℹ 124 more rows
hass_dolar <- dolar %>% 
  right_join(hass, by = c("mes","anio")) 

hass_dolar %>% 
  head(5) %>% 
  ftable()

anio

mes

precio_dolar

precio_aguacate_kg

2,012

6

1,792.232

3,471.00

2,012

7

1,785.141

3,459.50

2,012

8

1,806.341

3,543.50

2,012

9

1,801.948

3,792.00

2,012

10

1,805.674

3,661.25

hass_dolar <- hass_dolar %>% mutate(variacion_aguacate = 100*(precio_aguacate_kg -lag(precio_aguacate_kg))/lag(precio_aguacate_kg)) %>% mutate(variacion_dolar = 100*(precio_dolar -lag(precio_dolar))/lag(precio_dolar)) %>% filter(!is.na(variacion_aguacate))

hass_dolar
## # A tibble: 133 × 6
##     anio   mes precio_dolar precio_aguacate_kg variacion_aguacate
##    <dbl> <dbl>        <dbl>              <dbl>              <dbl>
##  1  2012     7        1785.              3460.             -0.331
##  2  2012     8        1806.              3544.              2.43 
##  3  2012     9        1802.              3792               7.01 
##  4  2012    10        1806.              3661.             -3.45 
##  5  2012    11        1821.              3580.             -2.21 
##  6  2012    12        1794.              2946             -17.7  
##  7  2013     1        1770.              2776.             -5.76 
##  8  2013     2        1792.              2732.             -1.60 
##  9  2013     3        1811.              3313.             21.3  
## 10  2013     4        1830.              3038.             -8.28 
## # ℹ 123 more rows
## # ℹ 1 more variable: variacion_dolar <dbl>

Modelo ingenuo

ggplot(data = hass_dolar,
       aes(x= variacion_dolar, y= variacion_aguacate)) +
geom_point()+ 
geom_hline(yintercept = mean(hass_dolar$variacion_aguacate),
           color = "red")+
geom_text(data=hass_dolar,
          aes(x= 1, y = mean(hass_dolar$variacion_aguacate),
              label = paste("Promedio, [%]:",
                            round(mean(hass_dolar$variacion_aguacate), 2))),
          hjust = 0.5, vjust = -0.1, color = "red"
) +
theme_light()

Calidad de ajuste del modelo ingenuo

Sea \(e_i = y_i - \bar{y}\) las diferencia entre la variación del precio del aguacate \(y_i\) y el promedio \(\bar{y}\). Dado el número de diferenciass, se hace necesario definir una métrica resumen.Por conveniencia se elije la suma de los cuadrados de las diferencias, lo cual permite la compensación de las diferencias negativas y positivas.

\[SCE_{\text{ingenuo}} = \sum^{n}_{i=1}e_i²=\sum^{n}_{i=1}(y_i - \bar{y})²\] Como primeras conclusiones se tiene que:

  1. Entre más grandes sean cada una de las distancias \(e_i\) individuales, más grande será SCE.
  2. Todas las distancias contribuyen con igual importancia al SCE, excepto en lo que se refiere a su magnitud no hay porque pensar que un distanciamiento de \(u\) unidades sea más importante que otro de las mismas \(u\) unidades. Esto puede ser obvio pero no lo es cuando, por ejemplo, queremos castigar más las distancias que se dan en la zona central del gráfico que las que se dan en los extremos del gráfico.
  3. El SCE es sensible a la cantidad de datos, razón por la cual entre más datos (es decir entre más grande sea n), más grande será SCE. Esto dificulta seriamente la posibilidad de comparar modelos que fueron calculados sobre una cantidad distinta de puntos.

De acuerdo con lo anterior se modifica la definición de desajuste como sigue:

\[MSE_{\text{ingenuo}} = \color{red}{\frac{1}{n}}\sum^{n}_{i=1}(y_i - \bar{y})²\] La medida de desajuste será el promedio de la suma de las diferencias cuadradas de cada dato \(y_i\) respecto a su media \(\bar{y}\), dicho de otra manera la varianza de la variable \(Y\) a predecir!!!!

# 💡 Varianza de los residuales respecto del modelo ingenuo, es la misma varianza de la variable a predecir.

Distancias entre cada dato \(y_i\) observado y el promedio (valor predicho \(\bar{y}\) por el modelo ingenuo)

hass_dolar %>% 
  ggplot(aes(x= variacion_dolar, y= variacion_aguacate)) +
  geom_point()+ 
  geom_hline(yintercept = mean(hass_dolar$variacion_aguacate))+
  geom_segment(aes(xend=variacion_dolar, yend=mean(variacion_aguacate)),
               col='red', lty='dashed')+
  theme_light()

## Modelo de regresión (lineal)

A continuación, se presenta el desarrollo de un modelo lineal que explique la relación entre las variables:

#Modelo de regresión lineal (Analítico)

x = hass_dolar$variacion_dolar
y = hass_dolar$variacion_aguacate

# b1 = cov(x,y) / (sigma_x)²
b1 <- cov(x,y) / var(x)
print(b1)
## [1] 0.0930811
# bo = y_barra - b1*x_barra
b0 <- mean(y) - b1*mean(x)
print(b0)
## [1] 0.7012181
residuales <- y - (b0 + b1*x)
n <- length(x)

sigma_2 <- sum(residuales^2)/(n-2)
print(sigma_2)
## [1] 65.35727
# Confirmación mediante la función lm

mod1 <- hass_dolar %>% lm(variacion_aguacate ~ variacion_dolar,.)
print(mod1$coefficients)
##     (Intercept) variacion_dolar 
##       0.7012181       0.0930811
resumen <-  summary(mod1)
(resumen$sigma)^2
## [1] 65.35727
parametros <- data.frame(metodo = c("Analítico","Función (lm)"), 
                         Beta_0 = c(b0,mod1$coefficients[1]),
                         Beta_1 = c(b1,mod1$coefficients[2]),
                         sigma_2 = c(sigma_2, (resumen$sigma)^2))

parametros %>% ftable()

metodo

Beta_0

Beta_1

sigma_2

Analítico

0.7012181

0.0930811

65.35727

Función (lm)

0.7012181

0.0930811

65.35727

Prueba de normalidad.

El mejor modelo para describir la relación entre la variable variación del precio del aguacate (\(y\)) y variación del precio del dólar(\(x\)), pensado desde la perspectiva de minimización de cuadrados del error y estando restringidos a la familia de modelos de regresión lineal con componente de error normal es:

\(y = 0.7 + 0.09x + e \text{ con e~N(0,65.4)}\)

El hecho de encontrar las mejores estimaciones de los betas para minimizar la función de pérdida, no garantiza que nuestro modelo induzca errores normales, por tal motivo conviene recordar lo siguiente:

💭 Cuando el modelo fue planteado fue supuesto que la distribución de los errores sería normal. Una vez construído el modelo, es necesario validar la suposición realizada.

🤔💭 ¿Cómo hacerlo ❔

En la siguiente tabla comparativa se presentan las ventajas y desventajas de las tres pruebas de normalidad (Kolmogorov-Smirnov, Lilliefors y Shapiro-Wilk) más usadas en estadística.

tabla_normalidad <- data.frame(
  "Prueba" = c("Kolmogorov-Smirnov (KS)", "Prueba de Lilliefors", "Prueba de Shapiro-Wilk (SW)"),
  "Ventajas" = c(
    "- Puede utilizarse para cualquier distribución teórica.\n- Es una prueba no paramétrica versátil.\n - Adecuada para muestras grandes.",
    "- Es específica para evaluar la normalidad.\n- Puede ser más adecuada para muestras pequeñas.\n - Utiliza estadísticas de prueba que se ajustan a la distribución estándar.",
    "- Es especialmente potente para muestras pequeñas.\n- Diseñada específicamente para evaluar la normalidad.\n- Sensible a desviaciones de la normalidad en cualquier parte de la distribución."
  ),  "Desventajas" = c(
    "- Puede ser menos poderosa en muestras pequeñas.\n - No es específica para la distribución normal.",
    "- Restringida a la comprobación de normalidad. \n - Menos potente en muestras grandes.\n- No es tan versátil como KS para otras distribuciones.",
    "- Más compleja de entender y aplicar.\n- No proporciona estimaciones de parámetros.\n- Puede ser menos adecuada para muestras muy grandes.\n- No es tan versátil como KS para otras distribuciones."))

# Imprimir la tabla con formato

tabla_normalidad %>% 
  ftable() %>% 
  align(i = NULL, j = c(2:3),
        align = "left", part = "all")

Prueba

Ventajas

Desventajas

Kolmogorov-Smirnov (KS)

- Puede utilizarse para cualquier distribución teórica.
- Es una prueba no paramétrica versátil.
- Adecuada para muestras grandes.

- Puede ser menos poderosa en muestras pequeñas.
- No es específica para la distribución normal.

Prueba de Lilliefors

- Es específica para evaluar la normalidad.
- Puede ser más adecuada para muestras pequeñas.
- Utiliza estadísticas de prueba que se ajustan a la distribución estándar.

- Restringida a la comprobación de normalidad.
- Menos potente en muestras grandes.
- No es tan versátil como KS para otras distribuciones.

Prueba de Shapiro-Wilk (SW)

- Es especialmente potente para muestras pequeñas.
- Diseñada específicamente para evaluar la normalidad.
- Sensible a desviaciones de la normalidad en cualquier parte de la distribución.

- Más compleja de entender y aplicar.
- No proporciona estimaciones de parámetros.
- Puede ser menos adecuada para muestras muy grandes.
- No es tan versátil como KS para otras distribuciones.

La elección de la prueba depende de varios factores, incluyendo el tamaño de la muestra, el conocimiento previo sobre la distribución de los datos y los objetivos del análisis. Ninguna prueba es perfecta y es importante considerar el contexto y las características específicas de los datos al seleccionar una prueba de normalidad.

Prueba Lilliefors:

# Paso 1: Ordenamos los datos de menor a mayor
n <- length(mod1$residuals)
df_residuals <- data.frame(residuals = mod1$residuals)
df_residuals <- df_residuals %>% 
                arrange(residuals)

# Paso 2: Estimamos los parámetros para la distribución normal teórica a partir de los datos

mean_residuals <- mean(df_residuals$residuals)
sd_residuals <- sd(df_residuals$residuals)

# Paso 3: Calculamos la función acumulada para cada valor de residual
cdf_teorica <- pnorm(df_residuals$residuals,
                      mean = mean_residuals,
                      sd = sd_residuals)

# Paso 4: Calculamos la máxima diferencia absoluta entre la densidad empírica y la teórica

# Método 1: Construir la función empírica usando fórmulas de R (ecdf) y luego tomar diferencias
#           absolutas entre valor empírico y teórico (enfoque KS)
cdf_empirica <- ecdf(df_residuals$residuals)
diferencias_absolutas <- abs(cdf_empirica(df_residuals$residuals) - cdf_teorica)
pos_estadistico_m1 <- which.max(diferencias_absolutas)
estadistico_m1 <- diferencias_absolutas[pos_estadistico_m1]

print(paste0("Este es el valor del estadístico: ", estadistico_m1," y esta es la posición en ",
             "la que ocurre la máxima diferencia ", pos_estadistico_m1))
## [1] "Este es el valor del estadístico: 0.0567370047041706 y esta es la posición en la que ocurre la máxima diferencia 82"
# Método 2: Construir manualmente los cálculos que permiten hallar la máxima diferencia
#           entre la empírica y la teórica usando la definición de la empírica como
#           función a trozos 📈

e_plus <- seq(1:n)/n
e_minus <- seq(0:(n-1))/n

D_plus <- e_plus - cdf_teorica
D_minus <- cdf_teorica - e_minus

pos_max_d_plus <- which.max(D_plus)
pos_max_d_minus <- which.max(D_minus)

estadistico_m2 <- max(D_plus[pos_max_d_plus], D_minus[pos_max_d_minus])
pos_estadistico_m2 <- function() {
  if(max(D_plus)>=max(D_minus)) {
    return(pos_max_d_plus)
    }else{
      return(pos_max_d_minus)
    }
  }

print(paste0("Este es el valor del estadístico: ", estadistico_m2," y esta es la posición en ",
             "la que ocurre la máxima diferencia ", pos_estadistico_m2()))
## [1] "Este es el valor del estadístico: 0.0567370047041706 y esta es la posición en la que ocurre la máxima diferencia 82"
# Comprobamos los resultados invocando la función de R que realiza estos cálculos automáticos

Lilliefors_test <- lillie.test(df_residuals$residuals)
print(Lilliefors_test)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  df_residuals$residuals
## D = 0.056737, p-value = 0.3681
estadistico_l <- Lilliefors_test$statistic
print(paste0("Este es el estadístico de Lilliefors usando paquetería de R: ", estadistico_l))
## [1] "Este es el estadístico de Lilliefors usando paquetería de R: 0.0567370047041706"
#Gráfico de Lilliefors

x_seg <- df_residuals$residuals[pos_estadistico_m1]
y_sup_seg <- cdf_teorica[pos_estadistico_m1]
y_inf_seg <- cdf_empirica(x_seg)

cat("x_seg: ", format(x_seg, digits=5), 
    " y_inf_seg: ", format(y_inf_seg, digits=5),
    " y_sup_seg: ", format(y_sup_seg, digits=5),
    sep='')
## x_seg: 1.2119 y_inf_seg: 0.61654 y_sup_seg: 0.5598
datos_para_grafico <- data.frame(
  residuales = df_residuals$residuals
  )

ggplot(datos_para_grafico, aes(x = residuales)) +
#  geom_density(color = "blue", fill = "lightblue", alpha = 0.5) +
  stat_function(fun = pnorm, args = list(mean = mean_residuals,
                                         sd = sd_residuals),
                color = "red", size = 1) +
  stat_ecdf(color = "green", size = 1) +
  geom_segment(aes(x = x_seg, y = y_inf_seg, xend = x_seg,
                   yend = y_sup_seg),
               color = "purple", size = 1, linetype = "solid") +
  geom_point(aes(x = x_seg, y = y_inf_seg),
             color = "purple",size = 3) +
  geom_point(aes(x = x_seg, y = y_sup_seg),
             color = "purple", size = 3) +
  annotate("text", x = x_seg , y = (y_inf_seg + y_sup_seg)/2, 
           label = paste0("Máxima Separación=",
                          format(estadistico_m1,
                                 digits=5)," 🤔💭", sep=''),
           color = "purple", size = 3, hjust = -0.05, vjust = 0) +
  coord_cartesian(xlim = c(min(datos_para_grafico$residuales),
                           max(datos_para_grafico$residuales))) +
  xlab("Residuales del modelo") +
  ylab("Probabilidad acumulada") +
  labs(title = "Esquema de funcionamiento de la prueba de Lilliefors") +
  theme_minimal()

# Probando normalidad del error. 

shapiro.test(mod1$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  mod1$residuals
## W = 0.98669, p-value = 0.2253
ks.test(mod1$residuals, "pnorm")
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  mod1$residuals
## D = 0.39524, p-value < 0.00000000000000022
## alternative hypothesis: two-sided
# library(lubridate)

hass_dolar$predicciones <- mod1$fitted.values
hass_dolar$residuales <-mod1$residuals
hass_dolar 
## # A tibble: 133 × 8
##     anio   mes precio_dolar precio_aguacate_kg variacion_aguacate
##    <dbl> <dbl>        <dbl>              <dbl>              <dbl>
##  1  2012     7        1785.              3460.             -0.331
##  2  2012     8        1806.              3544.              2.43 
##  3  2012     9        1802.              3792               7.01 
##  4  2012    10        1806.              3661.             -3.45 
##  5  2012    11        1821.              3580.             -2.21 
##  6  2012    12        1794.              2946             -17.7  
##  7  2013     1        1770.              2776.             -5.76 
##  8  2013     2        1792.              2732.             -1.60 
##  9  2013     3        1811.              3313.             21.3  
## 10  2013     4        1830.              3038.             -8.28 
## # ℹ 123 more rows
## # ℹ 3 more variables: variacion_dolar <dbl>, predicciones <dbl>,
## #   residuales <dbl>

De las anteriores pruebas, específicamente para la prueba de Lilliefors y Shapiro - Wilk, se obtuvo un p > 0.05. En este sentido, se concluye que los residuos del modelo siguen una distribución normal.

Prueba de independencia

# Gráfico de residuales vs valores ajustados

hass_dolar %>% 
  ggplot(aes(x= predicciones, y=residuales)) +
  geom_point()+ 
  theme_light()+
  ylab("Residuales") +
  xlab("Valor predicho")

# Prueba de independencia del error: Durbin-Watson 

resultado_dw <- dwtest(mod1)
print(resultado_dw)
## 
##  Durbin-Watson test
## 
## data:  mod1
## DW = 1.6015, p-value = 0.009904
## alternative hypothesis: true autocorrelation is greater than 0
# Prueba de independencia del error: Ljung-Box

p_values <- vector()
for (i in 1:12) {
  resultado_ljung_box <- Box.test(mod1$residuals, lag = i,
                                  type = "Ljung-Box")
  p_values[i] <-resultado_ljung_box$p.value
}

resultados_lb <- data.frame(
  lag = seq(1,12),
  p_value = p_values
)

print(resultado_ljung_box)
## 
##  Box-Ljung test
## 
## data:  mod1$residuals
## X-squared = 85.049, df = 12, p-value = 0.0000000000004454
print(resultados_lb)
##    lag               p_value
## 1    1 0.0208919974880731329
## 2    2 0.0063400452195925272
## 3    3 0.0000007036644118497
## 4    4 0.0000004708457750358
## 5    5 0.0000015209075917566
## 6    6 0.0000002601162144567
## 7    7 0.0000007237077230826
## 8    8 0.0000005256255420916
## 9    9 0.0000000019909318638
## 10  10 0.0000000042534712419
## 11  11 0.0000000025587461039
## 12  12 0.0000000000004454215

La prueba estadística de Durbin-Watson evalúa si existe autocorrelación de primer orden en los residuales, mejora el análisis gráfico por ser una prueba formal. Un valor de Durbin-Watson cercano a 2 indica independencia, mientras que valores significativamente diferentes de 2 pueden indicar autocorrelación.Dado que el estadístico DW = 1.6015, valor cercano a 2, se tiene evidencia estadística de la independencia entre las variables (no existe autocorrelación significativa entre los residuales del modelo). Sin embargo, de acuerdo con la prueba de Box - Ljung, existe evidencia estadística de autocorrelación de los residuales en múltiples rezagos. Por otro lado, del gráfico de Residuales estandarizados vs valores predichos no hay patrones evidentes y los residuales se distribuyen aleatoriamente alrededor de cero, un indicio de independencia.

# Residuales estandarizados vs valores predichos

hass_dolar %>% 
  ggplot(aes(x= predicciones, y=residuales/sd(residuales))) +
  geom_point()+ 
  theme_light()+
  ylab("Residuales estandarizados") +
  xlab("Valor predicho")

# Residuales estandarizados vs precio del dólar

hass_dolar %>% 
  ggplot(aes(x= variacion_dolar, y=residuales/sd(residuales))) +
  geom_point()+ 
  theme_light()+
  ylab("Residuales estandarizados") +
  xlab("variacion_dolar")

### Prueba de homocedasticidad

# Pruebas estadísticas formales
# Breusch-Pagan
resultado_breusch_pagan <- bptest(mod1)
print(resultado_breusch_pagan)
## 
##  studentized Breusch-Pagan test
## 
## data:  mod1
## BP = 0.57835, df = 1, p-value = 0.447
# White
resultado_white <- bptest(mod1,
                          varformula = ~ (variacion_dolar +
                                            I(variacion_dolar^2)),
                          data=hass_dolar)
print(resultado_white)
## 
##  studentized Breusch-Pagan test
## 
## data:  mod1
## BP = 0.66416, df = 2, p-value = 0.7174
# Implementación manual del test de White

#1. Construir el dataframe que relaciona el cuadrado del error con
#los términos lineales de la predictora y el término cuadrático
#(por ser modelo lineal simple no hay productos cruzados)

df_squared_error <- data.frame(
  squared_error = mod1$residuals ^ 2,
  variacion_dolar = hass_dolar$variacion_dolar,
  variacion_dolar_2 = hass_dolar$variacion_dolar^2
)

#2. Calcule un modelo lineal ajustado sobre el cuadrado del error regresado por el termino lineal y cuadrático del precio del dolar

modelo_white <- lm(data = df_squared_error,
                   squared_error ~ variacion_dolar + variacion_dolar_2)

#3. Calcule el estadístico de prueba como n*R^2 (con n=datos del dataframe de errores)
R2 <- summary(modelo_white)$`r.squared`
w_estadistico = nrow(df_squared_error)*R2
#4. Como el estadístico se distribuye ji-cuadrado con 2 grados de libertad (2 variables regresoras) se tiene que el p valor es:
p_valor = 1-pchisq(as.numeric(w_estadistico),2)
paste("BP = ",round(w_estadistico,4)," y p_valor=",round(p_valor,5))
## [1] "BP =  0.6642  y p_valor= 0.71743"

De la prueba de Breusch-Pagan y White, se obtuvo un p > 0.05. En este sentido, se concluye queexiste evidencia estadística para asumir homocedasticidad en los residuales del modelo. Por otro lado, del gráfico que se presenta a continuación, no existe un patrón específico que haga sospechar de la presencia de heterocedasticidad.

estimated_squared_error <- modelo_white$coefficients[1] + modelo_white$coefficients[2]*df_squared_error$variacion_dolar +modelo_white$coefficients[3]*df_squared_error$variacion_dolar_2

p<- ggplot(data = df_squared_error, aes(x=variacion_dolar,
                                        y=squared_error))+
  geom_point()+
  geom_line(aes(y=estimated_squared_error, color="red"))+
  labs(title="Modelo white sobre cuadrados del error",
         subtitle = paste("R²=",round(R2,4),
                          "W-Estadístico=",round(w_estadistico,4),
                          "p_valor=",round(p_valor,5)))+
  scale_color_manual(values=c("red"="blue"),
                     labels=c("Error cuadrado estimado"),
                     name="Modelo de White")

print(p)

### Conclusiones

En conclusión, se tiene que el modelo funciona, dado que:

  • Se tuvo evidencia estadística para grantizar independencia de primer orden en los residuales del modelo.
  • Se tuvo evidencia estadística para garantizar normalidad en los residuales del modelo
  • Se tuvo evidencia estadística para garantizar homocedasticidad en los residuales del modelo
  • Del modelo de regresión lineal planteado se puede concluir que, la variación del precio del aguacate es poco sensible a la variación del precio del dolar. En este sentido, se podría pensar que existen variables exógenas que explican la variación del precio del aguacate en el tiempo, aún cuando puedan presentarse variaciones importantes del precio del dolar.