NewTurn any lesson into a live trading bot with one prompt, using AgenKitagenkit.xyz

Part 3 · Data scienceLesson 1016 minQuant Bible §4.3, §4.5

Linear regression: β, the hat matrix, t and F

The one formula to know by heart, what the residual squares are, and how to tell a real coefficient from noise.

If you learn one formula by heart for quant interviews, make it this one. Linear regression is the workhorse of quant research: factor models, hedge ratios, signal testing and most first-pass alpha models are regressions.

The closed form

Stack the NN observations into a matrix XX (N×(p+1)N \times (p+1), with a column of ones for the intercept) and a vector yy. Minimising RSS⁡(β)=(y−Xβ)⊤(y−Xβ)\operatorname{RSS}(\beta) = (y - X\beta)^\top(y - X\beta) means setting its gradient to zero:

∂RSS⁡∂β=−2X⊤(y−Xβ)=0⟹β^=(X⊤X)−1X⊤y\frac{\partial \operatorname{RSS}}{\partial \beta} = -2X^\top(y - X\beta) = 0 \quad\Longrightarrow\quad \boxed{\hat\beta = (X^\top X)^{-1}X^\top y}

The fitted values are y^=Xβ^=X(X⊤X)−1X⊤y=Hy\hat y = X\hat\beta = X(X^\top X)^{-1}X^\top y = Hy. The hat matrix H=X(X⊤X)−1X⊤H = X(X^\top X)^{-1}X^\top “puts the hat on yy”: it is the orthogonal projection of yy onto the column space of XX. Least squares finds the point in the space your features can reach that is closest to the data, and the residual y−y^y - \hat y is perpendicular to every feature.

With one input, the slope and intercept are just covariances:

β^1=Cov⁡(X,Y)Var⁡(X),β^0=yˉ−β^1xˉ.\hat\beta_1 = \frac{\operatorname{Cov}(X, Y)}{\operatorname{Var}(X)}, \qquad \hat\beta_0 = \bar y - \hat\beta_1 \bar x .
Figure 10.1A regression plane through a 3D cloud
Two inputs, one output: least squares fits a plane and the residuals are the vertical sticks. Each new sample leaves a ghost of the old plane. Push the correlation between the inputs towards 1 and the ghosts fan out around the diagonal: that is multicollinearity, seen directly.
Figure 10.2Drag-the-points regression
Drag points or tap to add them. Least squares picks the line that minimises the total orange area: each square’s side is one residual. The readout gives the slope’s standard error and t-statistic. Try the brainteasers: regress x on y, or count every point twice.

When X⊤XX^\top X isn’t invertible

If one column is an exact linear combination of others (say x2=3x1x_2 = 3x_1, or a full set of dummy variables plus an intercept), X⊤XX^\top X is singular. The fitted values y^\hat y are still the unique projection; only the coefficients stop being unique, because there is more than one way to write the same projection.

Is a coefficient real? The t-test

Estimate the noise variance with N−p−1N - p - 1 degrees of freedom (one is used up by each coefficient and the intercept):

σ^2=1N−p−1∑i=1N(yi−y^i)2.\hat\sigma^2 = \frac{1}{N - p - 1}\sum_{i=1}^{N}(y_i - \hat y_i)^2 .

If errors are uncorrelated with constant variance, Var⁡(β^)=(X⊤X)−1σ2\operatorname{Var}(\hat\beta) = (X^\top X)^{-1}\sigma^2. To test H0:βj=0H_0: \beta_j = 0, standardise:

zj=β^jσ^vj,vj=[(X⊤X)−1]jj,z_j = \frac{\hat\beta_j}{\hat\sigma\sqrt{v_j}}, \qquad v_j = \big[(X^\top X)^{-1}\big]_{jj},

which follows a tN−p−1t_{N-p-1} distribution under the null. ∣zj∣>2|z_j| > 2 is the usual rule of thumb for “significant”, and β^j±2 se⁡(β^j)\hat\beta_j \pm 2\,\operatorname{se}(\hat\beta_j) is an approximate 95% interval (1.96 is the exact normal quantile).

For a single input, se⁡(β^)≈σεn σX\operatorname{se}(\hat\beta) \approx \dfrac{\sigma_\varepsilon}{\sqrt n\,\sigma_X}: precision improves with more data, less noise, and more spread in the input.

Testing groups: the F-statistic

Three correlated features can each look insignificant while together they matter. Compare the full model (RSS₁, p1p_1 coefficients) with one that drops the group (RSS₀, p0p_0):

F=(RSS⁡0−RSS⁡1)/(p1−p0)RSS⁡1/(N−p1−1).F = \frac{(\operatorname{RSS}_0 - \operatorname{RSS}_1)/(p_1 - p_0)}{\operatorname{RSS}_1/(N - p_1 - 1)} .

A large FF says the dropped group carried real information. A typical workflow: run t-tests, collect everything with ∣z∣<2|z| < 2, then F-test that group before deleting it.

Multiple regression is many simple ones

Regression by successive orthogonalisation (Gram–Schmidt) shows what a multiple-regression coefficient means. Regress xjx_j on all the other inputs and keep the residual zjz_j, the part of xjx_j nothing else explains. Then

β^j=⟨zj,y⟩⟨zj,zj⟩.\hat\beta_j = \frac{\langle z_j, y\rangle}{\langle z_j, z_j\rangle} .

So β^j\hat\beta_j is the effect of xjx_j after adjusting for every other input. Econometricians call this regression anatomy (the Frisch–Waugh–Lovell theorem). It also explains multicollinearity: if xjx_j is almost explained by the others, zjz_j is tiny, ⟨zj,zj⟩\langle z_j, z_j\rangle is small and se⁡(β^j)\operatorname{se}(\hat\beta_j) explodes.

The brainteasers interviewers ask

What does linear regression assume?

  • The relationship is linear in the parameters (you can still use x2x^2 or log⁡x\log x as features).
  • Errors average zero given the inputs, so there is no systematic bias. Normal errors are convenient for exact t-tests but not required.
  • No perfect multicollinearity, and ideally not much of the imperfect kind.
  • Homoskedasticity: the error variance doesn’t depend on the inputs. If it does, use heteroskedasticity-robust standard errors.
  • Errors are uncorrelated with each other (no autocorrelation) and with the inputs.

Regress Y on X, then X on Y. Is β₁ = 1/β₂?

No. The first minimises vertical distances, the second horizontal ones. In fact β1β2=Cov⁡(X,Y)2Var⁡(X)Var⁡(Y)=ρ2∈[0,1]\beta_1\beta_2 = \dfrac{\operatorname{Cov}(X,Y)^2}{\operatorname{Var}(X)\operatorname{Var}(Y)} = \rho^2 \in [0, 1], so they are reciprocals only if the fit is perfect. Turn on “Also regress x on y” in the figure.

You duplicate every data point. What happens?

β^\hat\beta doesn’t change (X⊤XX^\top X and X⊤yX^\top y both double, and the factors of two cancel). But the standard errors shrink by about 2\sqrt 2, so t-statistics grow. Duplicated or overlapping observations fake significance, a real danger with overlapping return windows.

Three highly correlated features: two look fine and the third has a huge standard error. What do you do?

That is multicollinearity. Options: drop the third (but it may carry unique information), combine the features (an average or a principal component), centre or transform them, or switch to ridge, lasso or principal-components regression (next two lessons).

In code

import numpy as np
rng = np.random.default_rng(8)

N, p = 200, 3
X = np.c_[np.ones(N), rng.standard_normal((N, p))]
beta_true = np.array([1.0, 2.0, 0.0, -1.0])
y = X @ beta_true + rng.standard_normal(N)

beta = np.linalg.solve(X.T @ X, X.T @ y)          # (X'X)^-1 X'y, solved stably
resid = y - X @ beta
sigma2 = resid @ resid / (N - p - 1)
se = np.sqrt(np.diag(np.linalg.inv(X.T @ X)) * sigma2)
print(np.round(beta, 3))
print(np.round(beta / se, 1))                     # t-stats: the zero coefficient has |t| < 2

# Duplicating the data: same beta, smaller standard errors
X2, y2 = np.r_[X, X], np.r_[y, y]
print(np.allclose(np.linalg.solve(X2.T @ X2, X2.T @ y2), beta))   # True

Check yourself

In a regression of y on x₁ and x₂, x₂ is almost perfectly correlated with x₁. What happens to se(β₁)?

Progress is saved in this browser only.