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) = Ω =
σ₁²0⋯00σ₂²⋯0⋮⋮⋱⋮00⋯σₙ²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)
V̂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)
V̂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
V̂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)
V̂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)
V̂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:
V̂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
| Estimator | Correction on each ê²ᵢ | Theoretical basis |
|---|---|---|
| HC0 | None | Consistent asymptotically; biased downward in finite samples |
| HC1 | n/(n−k) globally | Heuristic borrowed from homoskedastic case; global average of HC2 |
| HC2 | 1/(1−hᵢᵢ) per obs | Bias correction: E[ê²ᵢ/(1−hᵢᵢ)|X] ≈ σᵢ² |
| HC3 | 1/(1−hᵢᵢ)² per obs | Jackknife: 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.
