View of Lac Léman from Lausanne

Part 2: Heteroskedasticity and robust standard errors

May 2026

Okay, so the homoskedastic case was nice, but now we need to push one step furher: What happens when you cannot assume that all the errors are drawn from the same distribution / have the same variance?

Part 1 recap and the problem with relaxing homoskedasticity

True variance-covariance matrix under heteroskedasticity

Var(ε | X) = Ω =

σ₁²000σ₂²000σₙ²

Var(β̂ | X) = (XᵀX)⁻¹ XᵀΩX (XᵀX)⁻¹

The homoskedastic case is the special case Ω = σ²I, which collapses this to σ²(XᵀX)⁻¹.

Seeing it: heteroskedastic errors and what OLS does with them

Notice that now we don't have just a sigma^2 to estimate, but, at first glance, an entire nxn matrix. However, in order to estimate standard errors for your point estimates, you only need to estimate XᵀΩX, which is kxk, and contains only k*(k+1)/2 unique elements.

Notice that this is where things kind of go south with the n = 3 case. If you count, you are trying to estimate two coefficients, + 3 additional standard errors. It won't work very well. For full transparency, this is where I don't understand things perfectly in terms of what can "legally" be done. But in my understanding, people went with a Method of Moments estimator (HC0 described below), and then tried to proceed with different adjustments in order to correct for the fact that coefficients had been estimated / leverage of the observations.

Estimating Ω: the sandwich estimator and its small-sample corrections

HC0 — the basic sandwich (Eicker–Huber–White)

HC0(β̂) = (XᵀX)⁻¹ · (Σᵢ ê²ᵢ xᵢxᵢᵀ) · (XᵀX)⁻¹

xᵢ is the i-th row of X (as a column vector). The middle term is a k×k matrix — a weighted sum of outer products, one per observation.

What is leverage?

Leverage and the bias of ê²ᵢ

Hat matrix: P = X(XᵀX)⁻¹Xᵀ

Leverage of observation i: hᵢᵢ = Pᵢᵢ (the i-th diagonal of P)

Key result: E[ê²ᵢ | X] = σᵢ²(1 − hᵢᵢ)

High-leverage observations are pulled toward the fitted line, so their residuals are systematically smaller than the true noise — ê²ᵢ understimates σᵢ². The HC corrections inflate ê²ᵢ to correct for this.

HC0, HC1, HC2, HC3 — four ways to fix the bias

All four use the same sandwich shell — (XᵀX)⁻¹ · [meat] · (XᵀX)⁻¹ — and differ only in what they put inside the meat. They differ sharply in their theoretical pedigree: HC0 and HC1 are largely heuristic; HC2 and HC3 have real derivations.

HC0 — Eicker (1967) / White (1980)

HC0(β̂) = (XTX)−1 · [Σᵢ ê²ᵢ xᵢxᵢT] · (XTX)−1

Where it comes from

The meat we need is XᵀΩX = Σᵢ σᵢ² xᵢxᵢᵀ, but σᵢ² is unobserved. HC0 replaces each σᵢ² with ê²ᵢ — the squared OLS residual for observation i. By the law of large numbers, (1/n)Σᵢ ê²ᵢ xᵢxᵢᵀ converges in probability to (1/n)Σᵢ σᵢ² xᵢxᵢᵀ as n → ∞, so HC0 is consistent. The problem is finite-sample bias: ê²ᵢ systematically undershoots σᵢ², because OLS residuals are shrunk by the hat matrix — the fit already "saw" observation i. HC0 ignores this and tends to produce SEs that are too small in moderate samples.

HC1 — MacKinnon & White (1985) · Stata default

HC1(β̂) = (n/(n−k)) · (XTX)−1 · [Σᵢ ê²ᵢ xᵢxᵢT] · (XTX)−1

Where it comes from — and why it's a heuristic

HC1 transplants the homoskedastic degrees-of-freedom intuition into the sandwich. Under homoskedasticity, HC0 underestimates the true variance by exactly a factor of (n−k)/n — the same reason we divide by n−k rather than n when estimating σ². Multiplying HC0 by n/(n−k) exactly unbiases it in that special case.

Under heteroskedasticity, this is only approximately right. The bias in ê²ᵢ is observation-specific — it depends on hᵢᵢ — so applying a single global correction n/(n−k) is imprecise. HC1 is what you'd write down if you wanted to apply the homoskedastic intuition without thinking too hard. Importantly, HC1 is the global-average version of HC2: since Σᵢ hᵢᵢ = k, the average leverage is k/n, so the average of 1/(1−hᵢᵢ) across observations is approximately 1/(1−k/n) = n/(n−k). HC1 and HC2 agree when leverages are uniform across observations and diverge when a few observations have outsized leverage. It is Stata's default , robust because of historical convention, not because it is theoretically superior.

HC2 — MacKinnon & White (1985)

HC2(β̂) = (XTX)−1 · [Σᵢ (ê²ᵢ / (1−hᵢᵢ)) xᵢxᵢT] · (XTX)−1

Where it comes from — a real derivation

Start from the key result established in the leverage section: E[ê²ᵢ | X] = (1−hᵢᵢ)σᵢ². This says that ê²ᵢ is not an unbiased estimate of σᵢ² — it is biased downward by the factor (1−hᵢᵢ). The fix is immediate: divide by (1−hᵢᵢ) to get an approximately unbiased estimate of σᵢ² for each observation separately:

E[ê²ᵢ / (1−hᵢᵢ) | X] ≈ σᵢ²

Plugging this into the meat gives an estimator of XᵀΩX that is approximately unbiased observation by observation:

E[Σᵢ (ê²ᵢ/(1−hᵢᵢ)) xᵢxᵢᵀ | X] ≈ Σᵢ σᵢ² xᵢxᵢᵀ = XᵀΩX

This is a per-observation correction. Each residual is inflated by its own leverage factor, so high-leverage observations — which are pulled closest to the fitted line and therefore have the most downward-biased residuals — receive the largest correction. This is the right behavior, and it comes from an actual derivation rather than analogy with the homoskedastic case.

HC3 — MacKinnon & White (1985) / Davidson & MacKinnon (1993)

HC3(β̂) = (XTX)−1 · [Σᵢ (ê²ᵢ / (1−hᵢᵢ)²) xᵢxᵢT] · (XTX)−1

Where it comes from — the jackknife

HC3 comes from leave-one-out resampling. Define the leave-one-out residual for observation i as the prediction error you would get if you re-estimated β without using observation i:

êi(−i) = Yᵢ − xᵢᵀ β̂(−i)

Actually refitting the model n times would be expensive, but there is a beautiful closed-form identity (a consequence of the Sherman–Morrison formula):

êi(−i) = êᵢ / (1 − hᵢᵢ)

The leave-one-out residual is simply the in-sample residual divided by (1−hᵢᵢ) — no refitting needed. The jackknife variance estimator then uses these honest, leave-one-out residuals in the meat:

jack(β̂) ≈ (XᵀX)−1 · [Σᵢ (êi(−i))² xᵢxᵢᵀ] · (XᵀX)−1 =  (XᵀX)−1 · [Σᵢ ê²ᵢ/(1−hᵢᵢ)² xᵢxᵢᵀ] · (XᵀX)−1

That is HC3. The motivation for using leave-one-out residuals is that they are "honest" about how variable β̂ is: observation i did not help fit the model used to predict it, so the residual is not artificially deflated. HC3 is more conservative than HC2 — it overcorrects in large samples but behaves best in small samples or when leverage is concentrated in a few observations.

Summary

EstimatorCorrection on each ê²ᵢTheoretical basis
HC0NoneConsistent asymptotically; biased downward in finite samples
HC1n/(n−k) globallyHeuristic borrowed from homoskedastic case; global average of HC2
HC21/(1−hᵢᵢ) per obsBias correction: E[ê²ᵢ/(1−hᵢᵢ)|X] ≈ σᵢ²
HC31/(1−hᵢᵢ)² per obsJackknife: uses leave-one-out residual ê_i/(1−hᵢᵢ)

Which to use? In large samples (n > 250 or so), all four agree closely and HC0 is fine. In moderate samples HC1 is widely used by convention; HC2 or HC3 are more principled. In small samples, or when a few observations have outsized leverage, HC3 is the safest choice — it is more conservative and handles influential points better. R's sandwich package gives you all four; Stata defaults to HC1 by historical convention. Both choices are defensible; they reflect different traditions, not different correctnesses.