10 Multicolinealidad: detección, consecuencias y (no) soluciones {-}

10.1 🎯 Objetivo y motivación {-}

En este capítulo estudiamos el supuesto A3. Colinealidad imperfecta \((\mathrm{rango}(X)=K)\), por qué es necesario para identificar MCO y qué ocurre cuando las variables explicativas están altamente correlacionadas (multicolinealidad aproximada). Verás:

  • Implicaciones algebraicas: existencia de \((X'X)^{-1}\) y estabilidad numérica.
  • Consecuencias estadísticas: varianza inflada, estadísticos \(t\) pequeños, IC amplios.
  • Cómo detectar multicolinealidad (correlaciones, \(R^2\) auxiliares, VIF).
  • Qué no hacer (y por qué): eliminar variables o transformar puede ser peor que la enfermedad.
  • Ejemplos prácticos en Stata, R y Python.

📚 Colinealidad imperfecta: idea algebraica

10.1.1 Definición y condición de rango {-}

Considera

\[ y=\beta_{1}+\beta_{2}X_{2}+\cdots+\beta_{K}X_{K}+\epsilon,\qquad y=X\beta+\epsilon. \]

El supuesto A3 implica que \(X\in\mathbb{R}^{n\times K}\) tiene rango completo \((\mathrm{rango}(X)=K)\). Entonces:

\[ X'X \text{ es invertible},\quad |X'X|\neq 0,\quad (X'X)^{-1}\;\text{existe}. \]

Si hay dependencia lineal exacta entre columnas de \(X\), \(|X'X|=0\) y no podemos calcular \(\hat{\beta}=(X'X)^{-1}X'y\).

Con multicolinealidad aproximada, \(|X'X|\) es muy pequeño (mal condicionado): se puede invertir, pero los errores estándar explotan y la inferencia se degrada.

Ejemplo (intuición numérica). Si

\[ X=\begin{bmatrix} 1 & 3 & 7\\ 1 & 2 & 5\\ 1 & 4 & 9\\ \vdots\\ 1 & 6 & 13.5 \end{bmatrix}, \]

las dos últimas columnas están casi en proporción: \(|X'X|\) resulta cercano a 0.


🧩 Modelo particionado y consecuencias de la multicolinealidad

Escribe el modelo como

\[ y=X_r\beta_r + X_s\beta_s + \epsilon,\qquad X=[X_r\;X_s]. \]

Define la matriz aniquiladora respecto a \(X_s\):

\[ M_s = I_n - X_s(X_s'X_s)^{-1}X_s'. \]

Premultiplicando el modelo por \(M_s\) y usando que \(M_s X_s=0\):

\[ M_s y = M_s X_r \beta_r + \epsilon. \]

Ecuaciones normales (premultiplicando por \(X_r'\)):

\[ X_r' M_s y = X_r' M_s X_r \hat{\beta}_r. \]

Por tanto,

\[ \boxed{\;\hat{\beta}_r=(X_r' M_s X_r)^{-1} X_r' M_s y\;}\tag{1} \]

Análogamente,

\[ \hat{\beta}_s=(X_s' M_r X_s)^{-1} X_s' M_r y,\qquad M_r=I_n-X_r(X_r'X_r)^{-1}X_r'. \]

Propiedades: insesgamiento y varianza

Insesgamiento. Bajo exogeneidad estricta \(E(\epsilon\mid X)=0\),

\[ E(\hat{\beta}_r\mid X_r,X_s)=\beta_r,\qquad E(\hat{\beta}_s\mid X_r,X_s)=\beta_s. \]

Varianza. Con varianza esférica \(Var(\epsilon\mid X)=\sigma^2 I_n\),

\[ Var(\hat{\beta}_r\mid X) = \sigma^2\,(X_r' M_s X_r)^{-1} = \sigma^2\big((M_s X_r)'(M_s X_r)\big)^{-1}. \]

Observa que \(M_s X_r\) son los residuos de regredir \(X_r\) sobre \(X_s\). Denótalos por \(\hat{\mu}_{X_r X_s}=M_sX_r\). Entonces

\[ Var(\hat{\beta}_r\mid X) = \sigma^2(\hat{\mu}_{X_r X_s}'\hat{\mu}_{X_r X_s})^{-1} = \sigma^2\frac{(X_r'X_r)^{-1}}{1-R^2_{x_r\cdot X_s}}. \]

Aquí \(R^2_{x_r\cdot X_s}\) es el \(R^2\) de la regresión auxiliar de \(X_r\) sobre \(X_s\) (sin constante si ya está en \(X_s\)). Conclusión: cuando \(X_r\) y \(X_s\) son muy colineales, \(R^2_{x_r\cdot X_s}\to 1\) y la varianza de \(\hat{\beta}_r\) se dispara; los \(t\) se hacen pequeños y los IC se ensanchan.

Mensaje clave: La multicolinealidad no genera sesgo en MCO (bajo exogeneidad), pero sí inflación de varianza. Es un problema de precisión y de identificación numérica.


10.1.2 📐 Intuición geométrica {-}

  • \(P_{X_s}=X_s(X_s'X_s)^{-1}X_s'\) proyecta sobre \(\mathrm{Col}(X_s)\); \(M_s=I-P_{X_s}\) proyecta ortogonalmente fuera de \(\mathrm{Col}(X_s)\).
  • Si \(X_r\) “cae casi” en \(\mathrm{Col}(X_s)\), entonces \(M_s X_r\) es muy pequeño → poca variación residual para identificar \(\beta_r\)grandes errores estándar.

10.2 🧪 “Controlar por otras variables” vía FWL {-}

Reescribiendo (1) con idempotencia de \(M_s\):

\[ \hat{\beta}_r=\big((M_sX_r)'(M_sX_r)\big)^{-1}(M_sX_r)'(M_sy). \]

Interpreta \(M_s X_r\) y \(M_s y\) como residuos de:

  • \(X_r\) contra \(X_s\) \(\Rightarrow\) \(\hat{\mu}_{X_rX_s}\),
  • \(y\) contra \(X_s\) \(\Rightarrow\) \(\hat{e}_{yX_s}\).

Entonces:

\[ \boxed{\;\hat{\beta}_r=(\hat{\mu}'\hat{\mu})^{-1}\hat{\mu}'\hat{e}\;},\quad \hat{\mu}\equiv \hat{\mu}_{X_rX_s},\;\hat{e}\equiv \hat{e}_{yX_s}. \]

Algoritmo FWL (3 pasos):

  1. Regrésale \(X_s\) a \(X_r\) y guarda residuos \(\hat{\mu}\).
  2. Regrésale \(X_s\) a \(y\) y guarda residuos \(\hat{e}\).
  3. Regrésala \(\hat{e}\) sobre \(\hat{\mu}\) \(\Rightarrow\) coeficientes parciales \(\hat{\beta}_r\).

10.3 🔎 Detección de multicolinealidad {-}

Exacta: se detecta de inmediato porque \((X'X)^{-1}\) no existe.

Aproximada: varias heurísticas útiles:

  1. Determinante de \(X'X\) cercano a 0 (o número de condición alto).
  2. Correlaciones altas entre regresores (p. ej., \(|\rho|>0.8\)).
  3. Regresión auxiliar \(X_i\) sobre \(X_{-i}\): \(R^2\) alto sugiere colinealidad.
  4. VIF (Variance Inflation Factor):

\[ \boxed{\;VIF_i=\frac{1}{1-R^2_{x_i\cdot X_{-i}}}\;} \]

Reglas de dedo: \(VIF>5\) (o \(>10\)) alerta seria.


🛠️ Ejemplos en Stata, R y Python

Stata

* Modelo principal
reg icfes2000 tam_clase p_educ p_univer p_secundaria

* 1) Correlaciones entre regresores
corr tam_clase p_edu_prom p_educ p_univer p_secundaria

* 2) Regresión auxiliar (ej.: p_edu_prom ~ otros X)
reg p_edu_prom p_educ p_univer p_secundaria tam_clase

* 3) VIF
vif

Lectura: \(R^2\) auxiliar alto y VIF grandes sugieren multicolinealidad. Si eliminas un regresor muy correlacionado, los VIF bajan, pero cuidado con sesgo por omisión.


R

# install.packages(c("car","PerformanceAnalytics"))
library(car)
library(PerformanceAnalytics)

# Ajuste
fit <- lm(icfes2000 ~ tam_clase + p_educ + p_univer + p_secundaria, data = df)
summary(fit)

# Correlaciones
Chart.Correlation(df[, c("tam_clase","p_edu_prom","p_educ","p_univer","p_secundaria")])

# Regresión auxiliar (ej.: p_edu_prom ~ otros X)
aux <- lm(p_edu_prom ~ p_educ + p_univer + p_secundaria + tam_clase, data = df)
summary(aux)  # R^2 auxiliar

# VIF
car::vif(fit)  # VIF por regresor

Python

import numpy as np, pandas as pd
import statsmodels.api as sm
from statsmodels.stats.outliers_influence import variance_inflation_factor

# Modelo principal
X = df[["tam_clase","p_educ","p_univer","p_secundaria"]].copy()
X = sm.add_constant(X)
y = df["icfes2000"].values
fit = sm.OLS(y, X).fit()
print(fit.summary())

# Matriz de correlaciones
print(df[["tam_clase","p_edu_prom","p_educ","p_univer","p_secundaria"]].corr())

# VIF
X_no_const = df[["tam_clase","p_educ","p_univer","p_secundaria"]].assign(const=1)
vifs = pd.Series(
    [variance_inflation_factor(X_no_const.values, i) for i in range(X_no_const.shape[1]-1)],
    index=["tam_clase","p_educ","p_univer","p_secundaria"]
)
print(vifs)

10.4 🚨 Qué hacer (y qué no) ante multicolinealidad {-}

  1. No hacer nada (frecuentemente lo mejor).

    • Es un problema de datos, no del estimador: MCO sigue siendo ELIO.
    • “Arreglos” agresivos pueden introducir sesgos o empeorar la inferencia.
  2. Más datos.

    • Aumentar \(n\) puede ayudar si los nuevos datos traen variación independiente.
    • En la práctica, difícil y no garantiza resolver colinealidad estructural.
  3. Incorporar evidencia externa (shrinkage/bayesiano).

    • Requiere supuestos/fuentes fuertes; cambia el problema a uno de regularización (ver ridge/LASSO en cursos de ML).
  4. Eliminar regresores.

    • Riesgo: sesgo por omisión si el regresor eliminado es relevante/causal.
    • A veces aceptable cuando la variable redundante mide casi lo mismo que otra y no es de interés sustantivo.
  5. Transformar variables (razones, dividir por un regresor, etc.).

    • Puede reducir colinealidad, pero introduce heterocedasticidad y complica la interpretación.

Regla de oro: Si la variable es clave para la pregunta causal, no la elimines solo por VIF alto. Reporta la imprecisión y discute limitaciones de identificación (falta de variación independiente).


10.5 🧪 Mini-demostración: varianza inflada por \(R^2\) auxiliar {-}

Theorem 10.1 Teorema (Inflación de varianza bajo colinealidad). Sea \(X=[X_r\;X_s]\). Bajo homocedasticidad y exogeneidad, \[ Var(\hat{\beta}_r\mid X)=\sigma^2\big(X_r'M_sX_r\big)^{-1} =\sigma^2\frac{(X_r'X_r)^{-1}}{1-R^2_{x_r\cdot X_s}}. \]

Proof. Usa \(M_s=I-P_{X_s}\) e identifica \(M_sX_r\) como residuo de regredir \(X_r\) en \(X_s\). Note que \[ X_r'M_sX_r = X_r'X_r - X_r'P_{X_s}X_r = (1-R^2_{x_r\cdot X_s})\,X_r'X_r. \] Invierte y factoriza \(\sigma^2\) para obtener la expresión.


🔬 Ejemplo reproducible: colinealidad simulada

Stata

clear all
set seed 1
set obs 2000
gen x1 = rnormal()
gen x2 = x1 + 0.02*rnormal()   // alta colinealidad
gen u  = rnormal()
gen y  = 1 + 2*x1 - 1*x2 + u

reg y x1 x2
vif
corr x1 x2

Lectura: \(\mathrm{corr}(x1,x2)\approx 1\) ⇒ VIF alto ⇒ \(se(\hat\beta)\) grandes; \(t\) pequeños pese a que ambos regresores son “reales”.

R

set.seed(1)
n <- 2000
x1 <- rnorm(n)
x2 <- x1 + 0.02*rnorm(n)
u  <- rnorm(n)
y  <- 1 + 2*x1 - 1*x2 + u
fit <- lm(y ~ x1 + x2)
summary(fit); car::vif(fit); cor(x1, x2)

Python

import numpy as np, statsmodels.api as sm
np.random.seed(1)
n = 2000
x1 = np.random.normal(size=n)
x2 = x1 + 0.02*np.random.normal(size=n)
u  = np.random.normal(size=n)
y  = 1 + 2*x1 - 1*x2 + u
X  = sm.add_constant(np.column_stack([x1,x2]))
print(sm.OLS(y, X).fit().summary())
print(np.corrcoef(x1, x2))

✅ Conclusiones clave

  • La multicolinealidad no sesga MCO (bajo exogeneidad), pero reduce drásticamente la precisión.
  • Detecta con correlaciones, regresiones auxiliares y VIF.
  • Evita “arreglos” que introduzcan sesgo por omisión. Si la variable es sustantiva, repórtala con sus grandes EE y discute la limitación de identificación (falta de variación independiente).

📘 Preguntas de repaso

  1. Explique por qué la condición \(\mathrm{rango}(X)=K\) es necesaria para identificar \(\hat{\beta}\). ¿Qué ocurre si \(|X'X|\approx 0\)?
  2. Partiendo del modelo particionado \(y=X_r\beta_r+X_s\beta_s+\epsilon\), derive \(\hat{\beta}_r=(X_r'M_sX_r)^{-1}X_r'M_sy\).
  3. Muestre que \(Var(\hat{\beta}_r\mid X)=\sigma^2\big[(1-R^2_{x_r\cdot X_s})X_r'X_r\big]^{-1}\). Interprete el rol de \(R^2\).
  4. ¿Por qué eliminar un regresor para bajar el VIF puede introducir sesgo por omisión? Dé un ejemplo aplicado.
  5. Diseñe una estrategia empírica para diagnosticar multicolinealidad y reportarla responsablemente en un paper.

10.6 🧰 Apéndice: comandos útiles {-}

Stata

* Diagnóstico rápido
corr X*
estat vce, corr   // correlación de parámetros estimados
estat condition   // número de condición de X'X (si disponible)
vif

* Regresiones auxiliares (R^2)
foreach v of varlist x1 x2 x3 {
    reg `v' x1 x2 x3 if "`v'"!="`v'"
}

R

library(car)
library(MASS)

# Número de condición
X <- model.matrix(fit)[, -1]
kappa(X)          # grande => mal condicionado

# VIF
vif(fit)

Python

import numpy as np
from numpy.linalg import cond

X = df[["x1","x2","x3"]].to_numpy()
print(cond(X))  # número de condición

Checklist para papers: (i) reporte VIF/condición; (ii) discuta colinealidad esperada (p.ej., dummies anidadas, variables casi equivalentes); (iii) justifique mantener regresores sustantivos aunque inflen varianza; (iv) contraste robustez (reporte especificaciones alternativas con trade-offs claros).