The F-Test and F-Distribution › F-Test in Regression: Overall Model Significance
Machine Learning from ScratchAll chapters The F-Test and F-Distribution › F-Test in Regression: Overall Model SignificanceOne section · Sections in this chapter5 / 10 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Beyond comparing two variances, the F-test plays a central role in regression analysis. When you fit a regression model, an immediate question is: does this model explain any variation at all?
The ANOVA Decomposition
Every regression model partitions the total variation in the response variable into two components:
where:
- = : Total variation in
- = : Variation explained by the model
- = : Variation left unexplained
The F-test asks: is the explained variation large enough, relative to the unexplained variation, to conclude that the model has real predictive value?
The F-Statistic for Regression
where:
- = number of predictors (excluding intercept)
- = number of observations
- = "Mean Square" = sum of squares divided by degrees of freedom
Degrees of freedom:
- Numerator: (one for each predictor)
- Denominator: (residual degrees of freedom)
Null hypothesis: (all predictor coefficients are zero)
If the null is true, none of the predictors help explain , and should be similar to , giving . A large F indicates the model explains more variation than expected by chance.
Worked Example: Multiple Regression
A researcher studies factors affecting house prices, fitting a model with square footage and number of bedrooms as predictors.
import numpy as np
from scipy import stats
# Generate housing data
np.random.seed(42)
n = 50
sqft = np.random.uniform(1000, 3000, n)
bedrooms = np.random.randint(2, 6, n)
price = 50000 + 150 * sqft + 20000 * bedrooms + np.random.normal(0, 30000, n)
# Fit regression using linear algebra
X = np.column_stack([np.ones(n), sqft, bedrooms])
beta = np.linalg.lstsq(X, price, rcond=None)[0]
y_pred = X @ beta
# Calculate sums of squares
y_bar = np.mean(price)
ss_total = np.sum((price - y_bar) ** 2)
ss_residual = np.sum((price - y_pred) ** 2)
ss_regression = ss_total - ss_residual
# Degrees of freedom
p = 2 # number of predictors (sqft and bedrooms)
df_regression = p
df_residual = n - p - 1
df_total = n - 1
# Mean squares
ms_regression = ss_regression / df_regression
ms_residual = ss_residual / df_residual
# F-statistic and p-value
f_stat = ms_regression / ms_residual
p_value = stats.f.sf(f_stat, df_regression, df_residual)
# R-squared
r_squared = ss_regression / ss_total
adj_r_squared = 1 - (1 - r_squared) * (n - 1) / (n - p - 1)F-Test for Regression: House Price Model ================================================================= Model: Price = beta_0 + beta_1 * SquareFootage + beta_2 * Bedrooms + epsilon Fitted coefficients: Intercept (beta_0): $64,173 Square footage (beta_1): $147.43 per sqft Bedrooms (beta_2): $18,284 per bedroom ANOVA Table: ----------------------------------------------------------------- Source SS df MS F p ----------------------------------------------------------------- Regression 399,645,915,189 2 199,822,957,594 224.36 9.04e-25 Residual 41,860,284,034 47 890,644,341 Total 441,506,199,223 49 ----------------------------------------------------------------- R-squared: 0.9052 Adjusted R-squared: 0.9012 Interpretation: The model explains 90.5% of the variance in house prices. The F-test (F = 224.4, p < 0.001) confirms this is statistically significant.


Connection to R-Squared
The F-statistic is directly related to :
This shows that:
- Higher → larger F → smaller p-value
- More predictors () → penalizes the F-statistic (need more explained variance to be significant)
- Larger sample size () → more power to detect small as significant