~/blog

Simple Linear Regression

Jun 25, 20267 min readBy Mohammed Vasim
Machine LearningAIData Science

A real estate agent asks you: "I have six recent sales in this neighborhood. If a 1,000 sq ft house comes on the market, what's it worth?" You could take the average — $303k — but you'd ignore the obvious pattern: bigger houses sell for more. You need a formula that turns square footage into a price. That's simple linear regression: one input, one output, find the best line.

The derivation is short enough to do by hand, and doing it by hand is how you internalize why the slope formula involves covariance and variance — not just what the formula is. This is not the same as a lookup table where you check the closest past sale; a linear model gives you a prediction for any square footage, even ones you've never seen.

Anchor dataset:

python
import numpy as np
from sklearn.linear_model import LinearRegression

X = np.array([650, 850, 1100, 1400, 1600, 1900]).reshape(-1, 1)
y = np.array([180, 220, 280, 340, 370, 430])

The Plan — Three Steps to Simple Linear Regression

We'll work through three steps: first measure how bad a naive guess is, then derive the formulas for the optimal slope and intercept, then compute them by hand on our anchor data and verify with code.


Step 1 — The Loss: Sum of Squared Errors

The residual for sample is .

The loss is the sum of squared errors:

Why squared? It penalizes large errors more than small ones, treats over- and under-prediction symmetrically, and is differentiable everywhere — properties that allow a closed-form solution.

As a baseline, try the worst possible model: (always predict zero):

Our goal is to find and that drive SSE far below this.

Step 1 complete. SSE for the naive all-zeros model is 596,600. Every step from here drives this number down.

Step 2 — Deriving the OLS Formulas

We start by setting the partial derivatives of SSE with respect to and to zero — this finds the bottom of the bowl-shaped loss surface:

Solving this system yields the OLS normal equations:

The slope is the covariance between and divided by the variance of — how much moves per unit movement in , adjusted for 's own spread.

Step 2 complete. We have the formulas: and .

Step 3 — Computing OLS by Hand on the Anchor

Step 1: Summary statistics

Step 2: Per-sample products

650180−600−123.3336000074000
850220−400−83.3316000033333
1100280−150−23.33225003500
140034015036.67225005500
160037035066.6712250023333
1900430650126.6742250082333
Σ1110000222000

Step 3: Compute weights

Final model:

Step 3 complete. and . Each additional square foot adds $200 to predicted price.

Step 4 — Predictions and Residuals

650180183.33−3.3311.09
850220223.33−3.3311.09
1100280273.336.6744.49
1400340333.336.6744.49
1600370373.33−3.3311.09
1900430433.33−3.3311.09
SSE133.33

SSE dropped from 596600 (naive model) to 133.33 — a 4500× reduction. No other linear model can achieve lower SSE on this data; OLS is provably optimal among all unbiased linear estimators.

Step 4 complete. SSE at the optimal weights is 133.33, down from 596,600 at .

sq_ft price ($k) 650 900 1150 1550 1900 ŷ = 53.33 + 0.20·sqft w₀=53.33 −3.3 −3.3 +6.7 +6.7 −3.3 −3.3 rise/run=0.20

Step 5 — Code Verification

python
model = LinearRegression()
model.fit(X, y)

print(f"w₀ (intercept): {model.intercept_:.2f}")
print(f"w₁ (slope):     {model.coef_[0]:.4f}")
text
w₀ (intercept): 53.33
w₁ (slope):     0.2000

The sklearn default uses ordinary least squares with no regularization — it should match our hand derivation exactly. Verify by predicting a new house:

python
new_house = np.array([[1000]])
print(f"Predicted price for 1000 sq_ft: ${model.predict(new_house)[0]:.1f}k")
text
Predicted price for 1000 sq_ft: $253.3k

Manual check:

Step 5 complete. sklearn confirms , , prediction for 1,000 sq ft is $253.3k.

Assumptions

Four conditions are required for OLS to behave well:

  1. Linearity — the true relationship is .
  2. Independence — residuals are independent across samples.
  3. Homoscedasticity — the variance of residuals is constant (doesn't grow with ).
  4. Normality — residuals follow a normal distribution (needed for inference, not prediction).

Violation check: plot residuals vs fitted values. Random scatter around zero confirms the assumptions. A fan shape means heteroscedasticity. A curved pattern means the linearity assumption is wrong.

Key Formulas

FormulaExpression
Slope
Intercept
Prediction
SSE

The OLS closed form is unique to linear regression with MSE — it works because the loss is quadratic in the weights, which gives a single global minimum you can solve for directly. For logistic regression or neural networks, the loss has no such algebraic shortcut, which is why gradient descent (post 7) exists. Multiple linear regression (post 8) extends the same formulas to features using the matrix form .

A common mistake here is assuming linearity is a small constraint. It's not — if the true relationship between sq_ft and price curves (prices that plateau at large houses), the best-fit line will have systematic residual patterns regardless of how carefully you tune the weights. You'll see it immediately in a residual-vs-fitted plot: the residuals won't scatter randomly around zero; they'll curve. That's the signal to add polynomial features or switch model class, not to keep tweaking what you have.

Test Your Understanding

  1. For our 6-sample anchor, verify that the sum of residuals . Is this always true for OLS? Why?

  2. If you doubled all values (prices in $2k increments instead of $k), how would and change? Use the OLS formulas to derive this, not trial and error.

  3. The SSE dropped from 596600 to 133.33 with OLS weights. Could you find weights that give SSE = 0? If not, why not? If yes, what would that mean about the data?

  4. What is the residual for a house with sq_ft = 1250? Is the model over- or under-predicting?

  5. A colleague argues that maximizing is the same as minimizing SSE. Are they correct? Under what conditions would these objectives give different results?

Comments (0)

No comments yet. Be the first to comment!

Leave a comment