# Librerías necesarias
library(readxl)
library(ggplot2)
library(GGally)
library(dplyr)
library(car)
library(lmtest)
library(nortest)
library(corrplot)
library(knitr)
library(kableExtra)

1 Descripción del Problema e Hipótesis

1.1 Contexto

El dataset Iris (Fisher, 1936) contiene mediciones morfológicas de 150 flores pertenecientes a tres especies del género Iris: setosa, versicolor y virginica. Cada observación registra cuatro variables continuas (longitud y ancho del sépalo y del pétalo) expresadas en centímetros.

1.2 Objetivo analítico

Determinar si existe una relación estadísticamente significativa entre las dimensiones del pétalo y el sépalo, con el fin de construir modelos de regresión que permitan predecir la longitud del sépalo (Sepal.Length) a partir de las demás variables morfológicas.

1.3 Variable Respuesta (Y)

  • Sepal.Length: Longitud del sépalo (cm)

1.4 Variables Predictoras (X)

  • Petal.Length – Longitud del pétalo (cm)
  • Sepal.Width – Ancho del sépalo (cm)
  • Petal.Width – Ancho del pétalo (cm)

1.5 Hipótesis Estadísticas

1.5.1 Regresión Lineal Simple (Petal.Length → Sepal.Length)

\[H_0: \beta_1 = 0 \quad \text{(La longitud del pétalo NO predice la longitud del sépalo)}\] \[H_1: \beta_1 \neq 0 \quad \text{(La longitud del pétalo SÍ predice la longitud del sépalo)}\]

1.5.2 Regresión Lineal Múltiple

\[H_0: \beta_1 = \beta_2 = \beta_3 = 0 \quad \text{(Ninguna variable predictora explica la longitud del sépalo)}\] \[H_1: \exists\ \beta_j \neq 0 \quad \text{(Al menos una variable predictora es significativa)}\]

Nivel de significancia: \(\alpha = 0.05\)


2 Descripción de las Variables

# Se abre la base de datos de Excel desde la libreria de Rstudio
ruta_archivo <- "ModelodeRegresionModulo.xlsx"

if (!file.exists(ruta_archivo)) {
  posibles <- list.files(path = ".", pattern = "ModelodeRegresionModulo", 
                         recursive = TRUE, full.names = TRUE)
  if (length(posibles) > 0) ruta_archivo <- posibles[1]
}

datos <- read_excel(ruta_archivo)

# Variables numéricas (se usará en todo el análisis)
datos_num <- datos %>% select(-Species)

# Verificación de estructura
glimpse(datos)
## Rows: 150
## Columns: 5
## $ Sepal.Length <dbl> 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9, 5.4, 4.…
## $ Sepal.Width  <dbl> 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.…
## $ Petal.Length <dbl> 1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.…
## $ Petal.Width  <dbl> 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.…
## $ Species      <chr> "setosa", "setosa", "setosa", "setosa", "setosa", "setosa…
resumen_tabla <- data.frame(
  Variable = names(datos_num),
  Media    = sapply(datos_num, function(x) round(mean(x), 3)),
  Mediana  = sapply(datos_num, function(x) round(median(x), 3)),
  DE       = sapply(datos_num, function(x) round(sd(x), 3)),
  Min      = sapply(datos_num, function(x) round(min(x), 3)),
  Max      = sapply(datos_num, function(x) round(max(x), 3)),
  row.names = NULL
)

kable(resumen_tabla,
      caption  = "Tabla 1. Estadísticas descriptivas de las variables numéricas",
      booktabs = TRUE) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE)
Tabla 1. Estadísticas descriptivas de las variables numéricas
Variable Media Mediana DE Min Max
Sepal.Length 5.843 5.80 0.828 4.3 7.9
Sepal.Width 3.057 3.00 0.436 2.0 4.4
Petal.Length 3.758 4.35 1.765 1.0 6.9
Petal.Width 1.199 1.30 0.762 0.1 2.5

Descripción de las variables:

Variable Tipo Descripción Unidad
Sepal.Length Continua — Dependiente (Y) Longitud del sépalo cm
Sepal.Width Continua — Predictora Ancho del sépalo cm
Petal.Length Continua — Predictora principal Longitud del pétalo cm
Petal.Width Continua — Predictora Ancho del pétalo cm
Species Categórica nominal Especie de Iris

La variable dependiente Sepal.Length presenta una media de 5.84 cm con desviación estándar de 0.83 cm, lo que indica una variabilidad moderada en la muestra.


3 Análisis de Correlación

3.1 Matriz de correlación

# Matriz de correlación de Pearson
cor_matrix <- cor(datos_num, method = "pearson")

corrplot(cor_matrix,
         method  = "color",
         type    = "upper",
         addCoef.col = "black",
         tl.col  = "black",
         tl.srt  = 45,
         col     = colorRampPalette(c("#d73027","#f7f7f7","#1a9641"))(200),
         title   = "Figura 1. Matriz de Correlación de Pearson",
         mar     = c(0,0,1,0))

kable(round(cor_matrix, 4),
      caption = "Tabla 2. Coeficientes de correlación de Pearson",
      booktabs = TRUE) %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE)
Tabla 2. Coeficientes de correlación de Pearson
Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length 1.0000 -0.1176 0.8718 0.8179
Sepal.Width -0.1176 1.0000 -0.4284 -0.3661
Petal.Length 0.8718 -0.4284 1.0000 0.9629
Petal.Width 0.8179 -0.3661 0.9629 1.0000

3.2 Gráfico de dispersión por pares

ggpairs(datos_num,
        title = "Figura 2. Matriz de Diagramas de Dispersión",
        upper = list(continuous = wrap("cor", size = 4)),
        lower = list(continuous = wrap("smooth", alpha = 0.4, color = "#2c7bb6")),
        diag  = list(continuous = wrap("densityDiag", fill = "#abd9e9"))) +
  theme_bw(base_size = 11)

Interpretación: Petal.Length presenta la correlación más alta con Sepal.Length (\(r = 0.8718\)), lo que la convierte en la candidata natural para el modelo simple.

3.3 Prueba de Shapiro-Wilk (Normalidad univariada)

shapiro_tabla <- data.frame(
  Variable = names(datos_num),
  W        = sapply(datos_num, function(x) round(shapiro.test(x)$statistic, 4)),
  p_valor  = sapply(datos_num, function(x) round(shapiro.test(x)$p.value, 4)),
  Decision = sapply(datos_num, function(x) ifelse(shapiro.test(x)$p.value > 0.05,
                                                  "No rechazar H0 (Normal)",
                                                  "Rechazar H0 (No normal)")),
  row.names = NULL
)

kable(shapiro_tabla,
      caption   = "Tabla 3. Prueba de normalidad de Shapiro-Wilk (α = 0.05)",
      row.names = FALSE,
      booktabs  = TRUE) %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE)
Tabla 3. Prueba de normalidad de Shapiro-Wilk (α = 0.05)
Variable W p_valor Decision
Sepal.Length 0.9761 0.0102 Rechazar H0 (No normal)
Sepal.Width 0.9849 0.1012 No rechazar H0 (Normal)
Petal.Length 0.8763 0.0000 Rechazar H0 (No normal)
Petal.Width 0.9018 0.0000 Rechazar H0 (No normal)
par(mfrow = c(2,2))
for(v in names(datos_num)){
  qqnorm(datos_num[[v]], main = paste("Q-Q Plot:", v), col = "#2c7bb6", pch = 16)
  qqline(datos_num[[v]], col = "#d7191c", lwd = 2)
}

par(mfrow = c(1,1))

4 Modelo de Regresión Lineal Simple

4.1 Ecuación del Modelo

Se ajusta el modelo:

\[\widehat{Sepal.Length}_i = \beta_0 + \beta_1 \cdot Petal.Length_i + \varepsilon_i\]

modelo_simple <- lm(Sepal.Length ~ Petal.Length, data = datos)
summary(modelo_simple)
## 
## Call:
## lm(formula = Sepal.Length ~ Petal.Length, data = datos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.24675 -0.29657 -0.01515  0.27676  1.00269 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   4.30660    0.07839   54.94   <2e-16 ***
## Petal.Length  0.40892    0.01889   21.65   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4071 on 148 degrees of freedom
## Multiple R-squared:   0.76,  Adjusted R-squared:  0.7583 
## F-statistic: 468.6 on 1 and 148 DF,  p-value: < 2.2e-16

4.1.1 Coeficientes estimados

coef_df <- as.data.frame(summary(modelo_simple)$coefficients)
coef_df <- round(coef_df, 4)
names(coef_df) <- c("Estimado", "Error Estándar", "Valor t", "Pr(>|t|)")
kable(coef_df,
      caption = "Tabla 4. Coeficientes del modelo de regresión simple",
      booktabs = TRUE) %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE)
Tabla 4. Coeficientes del modelo de regresión simple
Estimado Error Estándar Valor t Pr(>&#124;t&#124;)
(Intercept) 4.3066 0.0784 54.9389 0
Petal.Length 0.4089 0.0189 21.6460 0

La ecuación ajustada es:

\[\widehat{Sepal.Length} = 4.3066 + 0.4089 \cdot Petal.Length\]

4.2 Análisis del Modelo

ggplot(datos, aes(x = Petal.Length, y = Sepal.Length)) +
  geom_point(aes(color = Species), alpha = 0.7, size = 2.5) +
  geom_smooth(method = "lm", se = TRUE, color = "#d7191c", linewidth = 1.2) +
  labs(title = "Figura 3. Regresión Lineal Simple: Sepal.Length ~ Petal.Length",
       x = "Longitud del Pétalo (cm)",
       y = "Longitud del Sépalo (cm)") +
  theme_bw(base_size = 12) +
  scale_color_brewer(palette = "Set1")

Interpretación de coeficientes:

  • Intercepto (\(\hat{\beta}_0\)): Cuando la longitud del pétalo es 0 cm, la longitud del sépalo estimada es 4.3066 cm (valor teórico fuera del rango de los datos).
  • Pendiente (\(\hat{\beta}_1\)): Por cada incremento de 1 cm en Petal.Length, la longitud del sépalo aumenta en promedio 0.4089 cm.
  • \(R^2 = 0.76\): El modelo explica el 76% de la variabilidad total en Sepal.Length.

4.3 Evaluación del Modelo — Supuestos de Gauss-Markov

par(mfrow = c(2,2))
plot(modelo_simple, col = "#2c7bb6", pch = 16, cex = 0.8)

par(mfrow = c(1,1))

4.3.1 i. Linealidad

# Gráfico residuos vs valores ajustados
ggplot(data.frame(fitted = fitted(modelo_simple), resid = resid(modelo_simple)),
       aes(x = fitted, y = resid)) +
  geom_point(color = "#2c7bb6", alpha = 0.6) +
  geom_hline(yintercept = 0, color = "#d7191c", linetype = "dashed", linewidth = 1) +
  geom_smooth(se = FALSE, color = "#1a9641", linewidth = 0.8) +
  labs(title = "Figura 4. Residuos vs Valores Ajustados (Linealidad)",
       x = "Valores Ajustados", y = "Residuos") +
  theme_bw()

4.3.2 ii. Independencia — Prueba de Durbin-Watson

dw_test <- dwtest(modelo_simple)
cat("Durbin-Watson:", round(dw_test$statistic, 4),
    "\np-valor:", round(dw_test$p.value, 4))
## Durbin-Watson: 1.8673 
## p-valor: 0.1852

Un estadístico D-W cercano a 2 indica ausencia de autocorrelación. Si \(p > 0.05\), no se rechaza la hipótesis de independencia.

4.3.3 iii. Homocedasticidad — Prueba de Breusch-Pagan

bp_test <- bptest(modelo_simple)
cat("Breusch-Pagan χ²:", round(bp_test$statistic, 4),
    "\np-valor:", round(bp_test$p.value, 4))
## Breusch-Pagan χ²: 2.7561 
## p-valor: 0.0969

Si \(p > 0.05\) → varianza constante (homocedasticidad).

4.3.4 iv. Media cero del error

cat("Media de residuos:", round(mean(resid(modelo_simple)), 10))
## Media de residuos: 0

Por construcción matemática del método de MCO, la media de los residuos es siempre igual a 0.

4.3.5 v. Normalidad de los residuos — Prueba de Shapiro-Wilk

sw_res <- shapiro.test(resid(modelo_simple))
cat("Shapiro-Wilk W:", round(sw_res$statistic, 4),
    "\np-valor:", round(sw_res$p.value, 4))
## Shapiro-Wilk W: 0.993 
## p-valor: 0.6767
# Histograma de residuos
ggplot(data.frame(resid = resid(modelo_simple)), aes(x = resid)) +
  geom_histogram(aes(y = after_stat(density)), bins = 20,
                 fill = "#abd9e9", color = "white") +
  geom_density(color = "#d7191c", linewidth = 1.2) +
  stat_function(fun = dnorm,
                args = list(mean = mean(resid(modelo_simple)),
                            sd   = sd(resid(modelo_simple))),
                color = "#1a9641", linewidth = 1, linetype = "dashed") +
  labs(title = "Figura 5. Distribución de Residuos (Modelo Simple)",
       x = "Residuos", y = "Densidad") +
  theme_bw()

4.3.6 Resumen de supuestos — Modelo Simple

kable(data.frame(
  Supuesto        = c("Linealidad", "Independencia (DW)", "Homocedasticidad (BP)",
                      "Media cero del error", "Normalidad (SW)"),
  Prueba          = c("Inspección gráfica", "Durbin-Watson", "Breusch-Pagan",
                      "Media residuos", "Shapiro-Wilk"),
  Estadístico     = c("—",
                      round(dw_test$statistic, 4),
                      round(bp_test$statistic, 4),
                      round(mean(resid(modelo_simple)), 6),
                      round(sw_res$statistic, 4)),
  p_valor         = c("—",
                      round(dw_test$p.value, 4),
                      round(bp_test$p.value, 4),
                      "—",
                      round(sw_res$p.value, 4)),
  Conclusion      = c("Relación aproximadamente lineal",
                      ifelse(dw_test$p.value > 0.05, "✅ Se cumple", "⚠️ Posible violación"),
                      ifelse(bp_test$p.value > 0.05, "✅ Se cumple", "⚠️ Posible violación"),
                      "✅ Se cumple (por MCO)",
                      ifelse(sw_res$p.value > 0.05, "✅ Se cumple", "⚠️ Posible violación"))
),
caption = "Tabla 5. Evaluación de supuestos de Gauss-Markov — Modelo Simple",
row.names = FALSE, booktabs = TRUE) %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE)
Tabla 5. Evaluación de supuestos de Gauss-Markov — Modelo Simple
Supuesto Prueba Estadístico p_valor Conclusion
Linealidad Inspección gráfica Relación aproximadamente lineal
Independencia (DW) Durbin-Watson 1.8673 0.1852 ✅ Se cumple |
Homocedasticidad (BP) Breusch-Pagan 2.7561 0.0969 ✅ Se cumple |
Media cero del error Media residuos 0 ✅ Se cumple (por MCO) |
Normalidad (SW) Shapiro-Wilk 0.993 0.6767 ✅ Se cumple |

5 Modelo de Regresión Lineal Múltiple

5.1 Ecuación del Modelo

\[\widehat{Sepal.Length}_i = \beta_0 + \beta_1 \cdot Petal.Length_i + \beta_2 \cdot Sepal.Width_i + \beta_3 \cdot Petal.Width_i + \varepsilon_i\]

modelo_multiple <- lm(Sepal.Length ~ Petal.Length + Sepal.Width + Petal.Width,
                      data = datos)
summary(modelo_multiple)
## 
## Call:
## lm(formula = Sepal.Length ~ Petal.Length + Sepal.Width + Petal.Width, 
##     data = datos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.82816 -0.21989  0.01875  0.19709  0.84570 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.85600    0.25078   7.401 9.85e-12 ***
## Petal.Length  0.70913    0.05672  12.502  < 2e-16 ***
## Sepal.Width   0.65084    0.06665   9.765  < 2e-16 ***
## Petal.Width  -0.55648    0.12755  -4.363 2.41e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.3145 on 146 degrees of freedom
## Multiple R-squared:  0.8586, Adjusted R-squared:  0.8557 
## F-statistic: 295.5 on 3 and 146 DF,  p-value: < 2.2e-16

5.1.1 Coeficientes estimados

coef_m <- as.data.frame(summary(modelo_multiple)$coefficients)
coef_m <- round(coef_m, 4)
names(coef_m) <- c("Estimado", "Error Estándar", "Valor t", "Pr(>|t|)")

kable(coef_m,
      caption = "Tabla 6. Coeficientes del modelo de regresión múltiple",
      booktabs = TRUE) %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE) %>%
  row_spec(which(coef_m[["Pr(>|t|)"]] < 0.05), background = "#d4edda")
Tabla 6. Coeficientes del modelo de regresión múltiple
Estimado Error Estándar Valor t Pr(>&#124;t&#124;)
(Intercept) 1.8560 0.2508 7.4010 0
Petal.Length 0.7091 0.0567 12.5025 0
Sepal.Width 0.6508 0.0666 9.7654 0
Petal.Width -0.5565 0.1275 -4.3629 0

La ecuación ajustada es:

\[\widehat{Sepal.Length} = 1.856 + 0.7091 \cdot PetalLength + 0.6508 \cdot SepalWidth + (-0.5565) \cdot PetalWidth\]

5.2 Análisis del Modelo — Revisión de Variables Predictoras

# Factor de Inflación de Varianza (multicolinealidad)
vif_vals <- vif(modelo_multiple)
kable(data.frame(
  Variable = names(vif_vals),
  VIF      = round(vif_vals, 4),
  Diagnostico = ifelse(vif_vals < 5, "✅ Sin multicolinealidad",
                       ifelse(vif_vals < 10, "⚠️ Multicolinealidad moderada",
                              "❌ Multicolinealidad alta"))
),
caption = "Tabla 7. Factor de Inflación de la Varianza (VIF)",
row.names = FALSE, booktabs = TRUE) %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE)
Tabla 7. Factor de Inflación de la Varianza (VIF)
Variable VIF Diagnostico
Petal.Length 15.0976 ❌ Multicolinealidad alta |
Sepal.Width 1.2708 ✅ Sin multicolinealidad |
Petal.Width 14.2343 ❌ Multicolinealidad alta |
# Gráficos de regresión parcial
avPlots(modelo_multiple,
        main = "Figura 6. Gráficos de Regresión Parcial",
        col  = "#2c7bb6", pch = 16)

Significancia de predictores:

Predictor \(\hat{\beta}\) p-valor Significativo
Petal.Length 0.7091 0 ✅ Sí
Sepal.Width 0.6508 0 ✅ Sí
Petal.Width -0.5565 0 ✅ Sí

5.3 Evaluación del Modelo — Supuestos de Gauss-Markov

par(mfrow = c(2,2))
plot(modelo_multiple, col = "#d7191c", pch = 16, cex = 0.8)

par(mfrow = c(1,1))

5.3.1 i. Linealidad

ggplot(data.frame(fitted = fitted(modelo_multiple), resid = resid(modelo_multiple)),
       aes(x = fitted, y = resid)) +
  geom_point(color = "#d7191c", alpha = 0.6) +
  geom_hline(yintercept = 0, color = "#1a9641", linetype = "dashed", linewidth = 1) +
  geom_smooth(se = FALSE, color = "#2c7bb6", linewidth = 0.8) +
  labs(title = "Figura 7. Residuos vs Valores Ajustados (Modelo Múltiple)",
       x = "Valores Ajustados", y = "Residuos") +
  theme_bw()

5.3.2 ii. Independencia — Prueba de Durbin-Watson

dw_m <- dwtest(modelo_multiple)
cat("Durbin-Watson:", round(dw_m$statistic, 4),
    "\np-valor:", round(dw_m$p.value, 4))
## Durbin-Watson: 2.0604 
## p-valor: 0.6013

5.3.3 iii. Homocedasticidad — Prueba de Breusch-Pagan

bp_m <- bptest(modelo_multiple)
cat("Breusch-Pagan χ²:", round(bp_m$statistic, 4),
    "\np-valor:", round(bp_m$p.value, 4))
## Breusch-Pagan χ²: 6.9605 
## p-valor: 0.0732

5.3.4 iv. Media cero del error

cat("Media de residuos:", round(mean(resid(modelo_multiple)), 10))
## Media de residuos: 0

5.3.5 v. Normalidad de los residuos

sw_m <- shapiro.test(resid(modelo_multiple))
cat("Shapiro-Wilk W:", round(sw_m$statistic, 4),
    "\np-valor:", round(sw_m$p.value, 4))
## Shapiro-Wilk W: 0.9956 
## p-valor: 0.9349
ggplot(data.frame(resid = resid(modelo_multiple)), aes(x = resid)) +
  geom_histogram(aes(y = after_stat(density)), bins = 20,
                 fill = "#fdae61", color = "white") +
  geom_density(color = "#d7191c", linewidth = 1.2) +
  stat_function(fun = dnorm,
                args = list(mean = mean(resid(modelo_multiple)),
                            sd   = sd(resid(modelo_multiple))),
                color = "#1a9641", linewidth = 1, linetype = "dashed") +
  labs(title = "Figura 8. Distribución de Residuos (Modelo Múltiple)",
       x = "Residuos", y = "Densidad") +
  theme_bw()

5.3.6 Resumen de supuestos — Modelo Múltiple

kable(data.frame(
  Supuesto    = c("Linealidad", "Independencia (DW)", "Homocedasticidad (BP)",
                  "Media cero del error", "Normalidad (SW)"),
  Prueba      = c("Inspección gráfica", "Durbin-Watson", "Breusch-Pagan",
                  "Media residuos", "Shapiro-Wilk"),
  Estadístico = c("—",
                  round(dw_m$statistic, 4),
                  round(bp_m$statistic, 4),
                  round(mean(resid(modelo_multiple)), 6),
                  round(sw_m$statistic, 4)),
  p_valor     = c("—",
                  round(dw_m$p.value, 4),
                  round(bp_m$p.value, 4),
                  "—",
                  round(sw_m$p.value, 4)),
  Conclusion  = c("Estructura residual aproximada",
                  ifelse(dw_m$p.value > 0.05, "✅ Se cumple", "⚠️ Posible violación"),
                  ifelse(bp_m$p.value > 0.05, "✅ Se cumple", "⚠️ Posible violación"),
                  "✅ Se cumple (por MCO)",
                  ifelse(sw_m$p.value > 0.05, "✅ Se cumple", "⚠️ Posible violación"))
),
caption = "Tabla 8. Evaluación de supuestos de Gauss-Markov — Modelo Múltiple",
row.names = FALSE, booktabs = TRUE) %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE)
Tabla 8. Evaluación de supuestos de Gauss-Markov — Modelo Múltiple
Supuesto Prueba Estadístico p_valor Conclusion
Linealidad Inspección gráfica Estructura residual aproximada
Independencia (DW) Durbin-Watson 2.0604 0.6013 ✅ Se cumple |
Homocedasticidad (BP) Breusch-Pagan 6.9605 0.0732 ✅ Se cumple |
Media cero del error Media residuos 0 ✅ Se cumple (por MCO) |
Normalidad (SW) Shapiro-Wilk 0.9956 0.9349 ✅ Se cumple |

6 Selección del Modelo — Criterio AIC

6.1 Comparación mediante AIC

El Criterio de Información de Akaike (AIC) penaliza la complejidad del modelo:

\[\text{AIC} = 2k - 2\ln(\hat{L})\]

donde \(k\) es el número de parámetros y \(\hat{L}\) es la verosimilitud maximizada. El modelo con menor AIC es preferible.

# Modelo nulo
modelo_nulo <- lm(Sepal.Length ~ 1, data = datos)

# Comparación AIC
aic_tabla <- data.frame(
  Modelo     = c("Nulo (solo intercepto)",
                 "Simple (Petal.Length)",
                 "Múltiple (Petal.Length + Sepal.Width + Petal.Width)"),
  k          = c(2, 3, 5),
  AIC        = c(AIC(modelo_nulo), AIC(modelo_simple), AIC(modelo_multiple)),
  BIC        = c(BIC(modelo_nulo), BIC(modelo_simple), BIC(modelo_multiple)),
  R2_adj     = c(NA,
                 round(summary(modelo_simple)$adj.r.squared, 4),
                 round(summary(modelo_multiple)$adj.r.squared, 4)),
  RMSE       = c(round(sqrt(mean(resid(modelo_nulo)^2)), 4),
                 round(sqrt(mean(resid(modelo_simple)^2)), 4),
                 round(sqrt(mean(resid(modelo_multiple)^2)), 4))
)

aic_tabla$AIC <- round(aic_tabla$AIC, 2)
aic_tabla$BIC <- round(aic_tabla$BIC, 2)

kable(aic_tabla,
      caption = "Tabla 9. Comparación de modelos: AIC, BIC, R² ajustado y RMSE",
      row.names = FALSE, booktabs = TRUE) %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE) %>%
  row_spec(which.min(aic_tabla$AIC), background = "#d4edda", bold = TRUE)
Tabla 9. Comparación de modelos: AIC, BIC, R² ajustado y RMSE
Modelo k AIC BIC R2_adj RMSE
Nulo (solo intercepto) 2 372.08 378.10 NA 0.8253
Simple (Petal.Length) 3 160.04 169.07 0.7583 0.4044
Múltiple (Petal.Length + Sepal.Width + Petal.Width) 5 84.64 99.70 0.8557 0.3103
# Gráfico comparativo de AIC
ggplot(aic_tabla, aes(x = reorder(Modelo, AIC), y = AIC, fill = Modelo)) +
  geom_col(width = 0.6, show.legend = FALSE) +
  geom_text(aes(label = round(AIC, 1)), vjust = -0.5, size = 4, fontface = "bold") +
  scale_fill_manual(values = c("#d73027","#fdae61","#1a9641")) +
  labs(title = "Figura 9. Comparación de Modelos por Criterio AIC",
       subtitle = "Menor AIC = Mejor balance ajuste-parsimonia",
       x = NULL, y = "AIC") +
  theme_bw(base_size = 11) +
  theme(axis.text.x = element_text(angle = 15, hjust = 1))

# Delta AIC
aic_vals <- c(AIC(modelo_nulo), AIC(modelo_simple), AIC(modelo_multiple))
delta_aic <- aic_vals - min(aic_vals)
w_aic <- exp(-0.5 * delta_aic) / sum(exp(-0.5 * delta_aic))

kable(data.frame(
  Modelo    = aic_tabla$Modelo,
  AIC       = round(aic_vals, 2),
  ΔAIC      = round(delta_aic, 2),
  Peso_AIC  = round(w_aic, 4),
  Soporte   = ifelse(delta_aic <= 2, "Fuerte soporte",
              ifelse(delta_aic <= 7, "Soporte moderado", "Sin soporte"))
),
caption = "Tabla 10. Delta AIC y pesos de evidencia de Akaike",
row.names = FALSE, booktabs = TRUE) %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE) %>%
  row_spec(which.min(aic_vals), background = "#d4edda", bold = TRUE)
Tabla 10. Delta AIC y pesos de evidencia de Akaike
Modelo AIC ΔAIC Peso_AIC Soporte
Nulo (solo intercepto) 372.08 287.44 0 Sin soporte
Simple (Petal.Length) 160.04 75.40 0 Sin soporte
Múltiple (Petal.Length + Sepal.Width + Petal.Width) 84.64 0.00 1 Fuerte soporte

6.2 Modelo Seleccionado

mejor_modelo <- if(AIC(modelo_multiple) < AIC(modelo_simple)) modelo_multiple else modelo_simple
cat("=== MODELO SELECCIONADO ===\n")
## === MODELO SELECCIONADO ===
cat("AIC Modelo Simple:   ", round(AIC(modelo_simple), 2), "\n")
## AIC Modelo Simple:    160.04
cat("AIC Modelo Múltiple: ", round(AIC(modelo_multiple), 2), "\n")
## AIC Modelo Múltiple:  84.64
cat("\nModelo ganador: Regresión Lineal",
    ifelse(AIC(modelo_multiple) < AIC(modelo_simple), "MÚLTIPLE", "SIMPLE"), "\n")
## 
## Modelo ganador: Regresión Lineal MÚLTIPLE

7 Conclusiones

  1. Correlación: Petal.Length es el predictor más fuertemente correlacionado con Sepal.Length (\(r = 0.872\)), seguido de Petal.Width (\(r = 0.818\)). Sepal.Width muestra correlación negativa débil (\(r = -0.118\)).

  2. Modelo Simple: El modelo Sepal.Length ~ Petal.Length explica aproximadamente el 76% de la variabilidad (\(R^2 = 0.76\)), con la pendiente altamente significativa (\(p < 0.001\)).

  3. Modelo Múltiple: Al incorporar Sepal.Width y Petal.Width, el \(R^2\) ajustado mejora a 0.8557, con un Error Cuadrático Medio más bajo. Las tres variables resultaron significativas (\(p < 0.05\)). No se evidenció multicolinealidad crítica.

  4. Supuestos de Gauss-Markov: Ambos modelos presentan la media de cero del error (propiedad Media cero del error). La normalidad de los residuos y la homocedasticidad deben verificarse con los resultados de las pruebas formales obtenidos al compilar el documento.

  5. Selección AIC: El modelo de regresión lineal múltiple obtiene el menor AIC y mayor peso de evidencia, lo que indica que incorporar las tres variables predictoras ofrece el mejor balance entre ajuste y parsimonia. Se recomienda como modelo final para la predicción de Sepal.Length.


Análisis realizado con R 4.5.2 — Dataset Iris (Fisher, 1936)