Written and maintained by CASRAI Editorial Board
Last updated
Hypothesis testing in linear regression asks whether the fitted relationship is distinguishable from no relationship. Three tests do almost all of the work: a t-test on one coefficient, an overall F-test on the whole model, and a nested (partial) F-test on a block of predictors. This guide shows which question each one answers, works two examples with the arithmetic visible, and ends with reporting and code. Its angle is the case other tutorials skip: two predictors that are each non-significant on a t-test while together they are clearly significant.
Hypothesis testing in linear regression: the definition
In hypothesis testing for linear regression, you state a null hypothesis about one or more model coefficients (almost always that they equal zero), compute a test statistic from the fitted model, and compare it with its sampling distribution under that null. For a single coefficient the statistic follows a t distribution; for several coefficients at once it follows an F distribution. A small p-value means the data would be unusual if the null were true. It does not measure effect size or the probability that the null is true; see the guide to what a p-value is and the explainer on the null hypothesis. For the wider modelling picture, start from regression analysis.
Formulas for the t-test and F-test, with every symbol explained
The model is y = β₀ + β₁x₁ + … + βₚxₚ + ε, fitted on n observations with p predictors plus an intercept. The estimates are b₀, b₁, …, bₚ.
t-test for one coefficient
H₀: βⱼ = 0 against H₁: βⱼ ≠ 0 (two-sided).
t = bⱼ / SE(bⱼ), compared with a t distribution on n − p − 1 degrees of freedom (n − 2 in simple regression).
- bⱼ: the estimated coefficient. SE(bⱼ): its estimated standard error. In simple regression SE(b₁) = √(MSE / Sxx).
- MSE = SSE / (n − p − 1): residual variance, where SSE = Σ(yᵢ − ŷᵢ)² is the residual sum of squares.
- Sxx = Σ(xᵢ − x̄)²: the spread of the predictor.
Overall F-test
H₀: β₁ = β₂ = … = βₚ = 0 (an intercept-only model is enough).
F = (SSR / p) / (SSE / (n − p − 1)), where SSR = SST − SSE is the sum of squares explained by the model and SST = Σ(yᵢ − ȳ)². Compare with an F distribution on p and n − p − 1 degrees of freedom. The test is right-tailed: only large F counts against H₀.
Nested (partial) F-test for a block of q predictors
F = ((SSE_reduced − SSE_full) / q) / (SSE_full / (n − p − 1)), where the reduced model omits the q predictors under test and p counts the predictors in the full model. Compare with F on q and n − p − 1 degrees of freedom. The overall F-test is the special case in which the reduced model contains only the intercept.
Worked example 1: the t-test, the F-test and F = t²
Illustrative data, invented for this guide: weeks of training (x) and samples a trainee technician processes per day (y), for n = 8 trainees.
| x (weeks) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| y (samples/day) | 12 | 15 | 14 | 19 | 21 | 20 | 26 | 27 |
- Means: x̄ = 4.5, ȳ = 19.25. Sums of squares: Sxx = 42, Sxy = 90, Syy = SST = 207.5.
- Slope b₁ = Sxy / Sxx = 90 / 42 = 2.1429. Intercept b₀ = 19.25 − 2.1429 × 4.5 = 9.6071.
- SSR = b₁ × Sxy = 192.857. SSE = 207.5 − 192.857 = 14.643. Residual df = n − 2 = 6, so MSE = 14.643 / 6 = 2.4405.
- SE(b₁) = √(2.4405 / 42) = 0.2411. t = 2.1429 / 0.2411 = 8.89 on 6 df, two-sided p = 0.00011. The 5% two-sided critical value is 2.447, so H₀: β₁ = 0 is rejected.
- F = SSR / MSE = 192.857 / 2.4405 = 79.02 on 1 and 6 df, p = 0.00011. With one predictor, F = t²: 8.89² = 79.02, and the two p-values are identical.
- 95% confidence interval for β₁: 2.1429 ± 2.447 × 0.2411 = [1.553, 2.733]. It excludes 0, which is the same decision as the t-test at α = 0.05. See confidence intervals.
- R² = SSR / SST = 192.857 / 207.5 = 0.929.
Worked example 2: two predictors that fail the t-test but pass the F-test
Illustrative data, invented for this guide: n = 10, outcome y = 14, 12, 13, 13, 12, 16, 22, 20, 27, 22; predictor x₁ = 2 to 11 in steps of 1; predictor x₂ = 2.1, 2.8, 4.3, 4.9, 6.2, 6.8, 8.3, 8.8, 10.4, 10.9. The two predictors are almost the same variable (r = 0.997). The full model has p = 2, so residual df = 10 − 2 − 1 = 7.
| Term | Estimate | SE | t (7 df) | p |
|---|---|---|---|---|
| Intercept | 7.397 | 2.192 | 3.37 | .012 |
| x₁ | −4.380 | 3.974 | −1.10 | .307 |
| x₂ | 5.828 | 3.945 | 1.48 | .183 |
Neither slope is significant. Now the joint test of H₀: β₁ = β₂ = 0. SST = 250.90 and SSE = 54.861, so SSR = 196.039.
F = (196.039 / 2) / (54.861 / 7) = 98.020 / 7.837 = 12.51 on 2 and 7 df, p = .0049 (5% critical value 4.737). The block is significant even though neither member is.
The same machinery tests one predictor. Dropping only x₂ gives a reduced model with SSE = 71.964, so F = (71.964 − 54.861) / 7.837 = 2.18 on 1 and 7 df, p = .183. That equals the square of x₂’s t statistic (1.48² = 2.18), which is why a single-coefficient t-test is a nested F-test with q = 1.
The cause is collinearity: each t-test asks what a predictor adds given the other is already in the model, and here each adds little beyond the other. The joint test asks whether the pair adds something beyond the intercept. Do not conclude that neither predictor matters; see multicollinearity and VIF.
Interpretation: which test answers which question
| Question | Test | Degrees of freedom | Where software reports it |
|---|---|---|---|
| Is this one coefficient different from zero, given the other terms? | t-test on bⱼ | n − p − 1 (with a constant) | R summary(lm) coefficients table; statsmodels tvalues, pvalues |
| Does the model as a whole beat an intercept-only model? | Overall F-test | p and n − p − 1 | R fstatistic; statsmodels fvalue, f_pvalue |
| Does a block of predictors add anything? | Nested (partial) F, or a Wald test of Rb = q | q and n − p − 1 | statsmodels f_test, wald_test; R anova(reduced, full) |
Reading the result: a p-value below your pre-set α (commonly 0.05) is evidence against H₀ for that test; a p-value above it means the data did not separate the coefficient from zero, not that it is zero. Report the estimate and its confidence interval alongside the p-value, because a tiny effect can be significant in a large sample and a large one can miss significance in a small sample. The t-statistic and F-statistic guides cover reading each in more depth, and the F table gives critical values.
Software details that change the numbers: statsmodels defines df_model as the number of regressors p excluding the constant, and df_resid as n − p − 1 when a constant is present (n − p when it is not). R’s summary.lm reports each coefficient’s estimate, standard error, t-statistic and two-sided p-value, and gives an F-statistic only for models that include non-intercept terms. SciPy’s linregress p-value tests the null that the slope is zero using a Wald test with the t distribution, and its standard error assumes normal residuals.
Assumptions and common mistakes
- The t and F reference distributions assume the classical conditions: a correctly specified linear mean, independent errors, constant error variance, and normally distributed errors (the normality condition matters most in small samples). Check residual plots and tests such as Breusch-Pagan for heteroscedasticity before trusting a p-value.
- Reading a non-significant t as “no effect.” Example 2 shows why this fails under collinearity. Test the block.
- Reading a significant overall F as “every predictor matters.” It says at least one coefficient differs from zero.
- Using the t-test to compare nested models with several extra terms. Use the nested F-test or a Wald test.
- Treating p as effect size. Pair it with b, the confidence interval and R².
- Running many coefficient tests without adjustment. With many predictors, some will pass at 0.05 by chance.
How to report it (APA style)
An APA-style sentence for example 1: Weeks of training predicted daily output, b = 2.14, 95% CI [1.55, 2.73], t(6) = 8.89, p < .001; the model explained 92.9% of the variance, F(1, 6) = 79.02, p < .001, R² = .93. For example 2: The two predictors jointly explained a significant share of variance, F(2, 7) = 12.51, p = .005, R² = .78, although neither coefficient was individually significant (x₁: t(7) = −1.10, p = .307; x₂: t(7) = 1.48, p = .183), consistent with their high correlation (r = .997). Give degrees of freedom in parentheses, report exact p-values where practical, and state the test for every figure.
How to calculate it in Excel, R or Python
Excel
Put x in A2:A9 and y in B2:B9. Enter =LINEST(B2:B9, A2:A9, TRUE, TRUE) as a 5 x 2 array: row 1 holds the slope and intercept, row 2 their standard errors, row 3 R² and the residual standard error, row 4 F and the residual df, row 5 SSR and SSE. Then t = slope / its SE, =T.DIST.2T(ABS(t), df) gives the p-value, and =F.DIST.RT(F, 1, df) gives the F p-value.
R
x <- 1:8; y <- c(12,15,14,19,21,20,26,27)
m1 <- lm(y ~ x); summary(m1) # t, p for each coefficient; overall F
m0 <- lm(y ~ 1); anova(m0, m1) # nested F-test; F equals t^2 here
confint(m1) # 95% intervals
Python
import numpy as np, statsmodels.api as sm
x = np.arange(1, 9); y = np.array([12,15,14,19,21,20,26,27])
m = sm.OLS(y, sm.add_constant(x)).fit()
print(m.tvalues, m.pvalues) # t = 8.89 for the slope
print(m.fvalue, m.f_pvalue) # F = 79.02, p = 0.00011
print(m.f_test(np.array([[0, 1]]))) # joint test of R b = 0; use more rows for a block
print(m.conf_int())
For a quick check without code, the linear regression calculator guide walks through slope inference by hand.
FAQ
What is the null hypothesis in linear regression?
For a coefficient, H₀: βⱼ = 0, meaning the predictor has no linear relationship with the outcome once the other terms are in the model. For the overall test, H₀ is that all slope coefficients are zero.
How do you do hypothesis testing for linear regression by hand?
Fit the line, compute SSE and MSE, divide each coefficient by its standard error to get t, and compare with a t distribution on n − p − 1 degrees of freedom. Example 1 shows every step.
What is the difference between the t-test and the F-test in regression?
The t-test judges one coefficient; the F-test judges a group of coefficients at once, or the whole model. With a single predictor they agree exactly, because F = t².
Why can the F-test be significant when no t-test is?
When predictors are strongly correlated, each adds little given the others, so the individual t statistics are small, while the group still explains variance. Example 2 is a case.
Does a significant regression mean the relationship is causal?
No. The tests address statistical association under the model’s assumptions, not causation.
Sources
- Kutner, M. H., Nachtsheim, C. J., Neter, J., and Li, W. Applied Linear Statistical Models (5th ed., McGraw-Hill/Irwin, 2005): t-tests on coefficients, the F-test for regression and the general linear test for nested models.
- American Psychological Association. Publication Manual of the American Psychological Association (7th ed., 2020): statistical reporting conventions.
- R Core Team. stats::summary.lm, https://stat.ethz.ch/R-manual/R-devel/library/stats/html/summary.lm.html (checked 2026-10-29).
- statsmodels. RegressionResults, https://www.statsmodels.org/stable/generated/statsmodels.regression.linear_model.RegressionResults.html (checked 2026-10-29).
- SciPy. scipy.stats.linregress, https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html (checked 2026-10-29).
Both datasets are illustrative and were constructed for this guide; all statistics were computed from them.







