03. Linear Regression - Introduction
Linear Regression - Complete Beginner’s Guide
Welcome to Linear Regression! 📈
Linear Regression is one of the simplest and most important machine learning algorithms. It’s the perfect starting point for your ML journey!
What is Linear Regression?
The Simple Explanation
Linear Regression is about finding the best straight line that fits your data.
Think of it like this:
- You have data points scattered on a graph
- You want to draw a straight line through them
- The line should be as close as possible to all points
- This line helps you predict future values
Real-World Example: Predicting House Prices
The Problem: You want to predict house prices based on size.
The Data: | Size (sq ft) | Price ($1000s) | |————–|—————| | 1000 | 200 | | 1500 | 300 | | 2000 | 400 | | 2500 | 500 | | 3000 | 600 |
What Linear Regression Does: It finds the best line through these points:
Price = 0.2 × Size
Now you can predict:
- 1800 sq ft house → 0.2 × 1800 = $360,000
- 3500 sq ft house → 0.2 × 3500 = $700,000
The Mathematics (Made Simple!)
The Line Equation
You probably remember this from school:
y = mx + b
In Linear Regression, we write it as:
ŷ = β₀ + β₁x
What the symbols mean:
- ŷ (y-hat) = Predicted value (what we’re trying to guess)
- x = Input feature (what we know)
- β₁ (beta-1) = Slope (how much y changes when x changes)
- β₀ (beta-0) = Intercept (value when x = 0)
Understanding Slope (β₁)
What it means: How much the output changes when the input increases by 1.
Example:
- If β₁ = 0.2 (house price example)
- Every additional square foot adds $0.2 thousand ($200)
- 1000 sq ft → $200,000
- 1001 sq ft → $200,200
Visual:
Price
↑
│ /
│ /
│ / (slope = 0.2)
│ /
│/
└─────────→ Size
Understanding Intercept (β₀)
What it means: The predicted value when x = 0.
Example:
- If β₀ = 50
- A house with 0 sq ft would cost $50,000
- This represents the “base price” (land, permits, etc.)
Note: Sometimes intercept doesn’t make sense in reality (a 0 sq ft house), but it’s still part of the equation.
How Does It Work? (The Magic Behind It)
The Goal: Minimize Errors
Linear Regression tries to find the line that minimizes the total error.
What is Error?
Error = Actual Value - Predicted Value
Example:
- Actual price: $320,000
- Predicted price: $300,000
- Error: $320,000 - $300,000 = $20,000
The Cost Function (Sum of Squared Errors)
We square the errors for two reasons:
- Make all errors positive (don’t cancel out)
- Penalize large errors more
Formula:
Cost = Σ(y - ŷ)²
Visual:
Actual point: ●
Predicted: |
| ← Error
|
The line with the smallest cost is the best line!
How It Finds the Best Line
Now we know the model wants to minimize the cost (errors). But HOW does it actually find the best line? There are two main methods. Let’s understand each one with simple examples!
Method 1: Ordinary Least Squares (OLS) 📐
🎯 The Simple Idea
OLS is like solving a math puzzle with a calculator.
Instead of trying lots of different lines and picking the best one, OLS uses a mathematical formula to instantly calculate the perfect line in ONE step!
🍕 Pizza Analogy
Imagine you want to cut a pizza into exactly equal slices:
Bad way (trial and error):
- Cut a slice… too big!
- Cut another… too small!
- Try again… still wrong!
- Keep trying for hours
OLS way (formula):
- You know there are 8 people
- 360° ÷ 8 = 45° per slice
- Cut perfectly the FIRST time!
That’s OLS! It uses a formula to find the answer directly.
📊 What It Actually Does
OLS finds the line that minimizes the sum of squared errors:
For each data point:
1. Find the error (actual - predicted)
2. Square the error (so negatives don't cancel positives)
3. Add up all squared errors
4. Find the line where this sum is SMALLEST
Why “squared”?
Imagine these errors: +5, -5, +3, -3
- Sum: 0 (looks perfect, but it’s not!)
- Squared sum: 25+25+9+9 = 68 (shows real error)
Squaring makes all errors positive AND penalizes big errors more!
🧮 The Math (Simple Version)
For a simple line y = β₀ + β₁x, OLS calculates:
β₁ (slope) = Σ((x - x̄)(y - ȳ)) / Σ((x - x̄)²)
β₀ (intercept) = ȳ - β₁ × x̄
Where:
x̄ = average of x values
ȳ = average of y values
Σ = sum of all values
Don’t worry about memorizing this! Python does it for you:
from sklearn.linear_model import LinearRegression
model = LinearRegression() # Uses OLS by default!
model.fit(X, y)
✅ When to Use OLS
| Use OLS When | Don’t Use OLS When |
|---|---|
| ✅ Small/medium dataset (< 100k rows) | ❌ Huge dataset (millions of rows) |
| ✅ Few features (< 1000) | ❌ Massive features (>10,000) |
| ✅ Want exact answer | ❌ Need to update model online |
| ✅ Memory is enough | ❌ Memory is limited |
🎯 OLS Pros and Cons
Pros:
- ✅ Exact solution - finds THE best answer
- ✅ One-shot - no iterations needed
- ✅ Fast for small data
- ✅ No tuning required
Cons:
- ❌ Slow for big data (matrix calculations)
- ❌ Requires lots of memory (stores entire matrix)
- ❌ Doesn’t work for very complex models
Method 2: Gradient Descent 🏔️
🎯 The Simple Idea
Gradient Descent is like rolling a ball down a hill.
Instead of solving with a formula, it gradually adjusts the line, making it better and better with each step until it reaches the bottom (minimum error).
🥣 The Bowl Analogy (Simplest Version!)
Imagine a marble inside a bowl:
\ /
\ /
\ /
\ 🔴 / ← Marble starts at top
\ /
\ /
\ /
\______/ ← Bottom (what we want!)
What happens?
- The marble naturally rolls downhill
- It keeps rolling until it reaches the bottom
- The bottom = lowest error = best line!
Gradient Descent does the same thing:
- Start at a random spot (top of bowl)
- Roll down toward lower error
- Stop at the bottom (best answer!)
🔢 Simple Number Example
Let’s say we want to find the number that gives the smallest error. Think of it as finding the bottom of this bowl:
Cost (error) at different positions:
| Position | Cost (Error) |
|---|---|
| 0 | 25 |
| 1 | 16 |
| 2 | 9 |
| 3 | 4 |
| 4 | 1 ← bottom! |
| 5 | 4 |
| 6 | 9 |
| 7 | 16 |
Visually:
Cost
25 ●
│
16 │ ● ●
│
9 │ ● ●
│
4 │ ● ●
│
1 │ ● ← minimum!
└──────────────────────────────────
0 1 2 3 4 5 6 7 Position
Gradient Descent walks along this curve to find Position = 4 (the minimum).
👣 Step-by-Step Walk
Let’s say we start at Position 0 with learning rate = 1:
Step 1: Position = 0
Cost = 25
Which way is down? → RIGHT (toward Position 4)
Take 1 step → New position = 1
Step 2: Position = 1
Cost = 16
Which way is down? → RIGHT
Take 1 step → New position = 2
Step 3: Position = 2
Cost = 9
Which way is down? → RIGHT
Take 1 step → New position = 3
Step 4: Position = 3
Cost = 4
Which way is down? → RIGHT
Take 1 step → New position = 4
Step 5: Position = 4
Cost = 1 ← MINIMUM!
Which way is down? → Nowhere! We're at the bottom!
STOP ✅
We found the answer in 4 steps! 🎉
🎯 How Does It Know Which Way to Go?
The gradient tells us the direction. It’s just the slope at our current position:
| At Position | Slope (Gradient) | Meaning |
|---|---|---|
| 0 | Steep downhill → right | Go right (big step) |
| 2 | Gentle downhill → right | Go right (smaller step) |
| 4 | Flat (slope = 0) | STOP - we’re at bottom! |
| 6 | Gentle downhill → left | Go left |
| 8 | Steep downhill → left | Go left (big step) |
Key insight: The steeper the slope, the bigger the step. When slope = 0, we stop!
🧮 The Algorithm (Plain English)
REPEAT until cost stops changing:
1. Where am I right now? (current position)
2. Which way is downhill? (calculate gradient)
3. Take a step in that direction
New position = Old position - (learning_rate × gradient)
4. Did I reach the bottom? If yes, STOP!
That’s it! Just 4 simple steps repeated until you find the answer.
🎚️ The Learning Rate (Step Size)
The learning rate is how big your steps are. This is CRITICAL!
Using our bowl example (bottom at Position 4), let’s see what happens with different step sizes:
Too Small (learning rate = 0.1) 🐌
Starting at Position 0, taking tiny 0.1 steps:
Position: 0 → 0.1 → 0.2 → 0.3 → 0.4 → 0.5 → ... → 4.0
(takes 40 steps to reach bottom!)
Problem: Takes forever!
Too Large (learning rate = 5) 💥
Starting at Position 0, taking giant 5-step leaps:
Step 1: Position 0 → jump to Position 5 (overshot! bottom was at 4)
Step 2: Position 5 → jump to Position 0 (overshot again!)
Step 3: Position 0 → jump to Position 5 (still overshooting!)
...keeps bouncing, never settles!
Problem: Bounces back and forth forever!
Just Right (learning rate = 1) ✅
Starting at Position 0, taking 1-step walks:
Position: 0 → 1 → 2 → 3 → 4 (bottom!)
(reached in 4 steps)
Perfect: Fast and accurate!
📊 Summary Table:
| Learning Rate | Behavior | Steps to Bottom |
|---|---|---|
| 0.01 (tiny) | Slow crawl | ~400 steps 🐌 |
| 0.1 (small) | Careful walk | 40 steps |
| 1 (just right) | Efficient | 4 steps ✅ |
| 5 (large) | Wild bouncing | Never! 💥 |
| 10 (huge) | Flies off | Diverges ❌ |
Common learning rates in real ML: 0.001, 0.01, 0.1 (depends on problem)
# Example with sklearn
from sklearn.linear_model import SGDRegressor
model = SGDRegressor(learning_rate='constant', eta0=0.01)
# eta0 = 0.01 means step size of 0.01
🎯 Three Types of Gradient Descent
1. Batch Gradient Descent
Use ALL data to calculate each step.
✅ Most accurate
❌ Slow for big data
❌ Uses lots of memory
2. Stochastic Gradient Descent (SGD)
Use ONE random data point per step.
✅ Very fast
✅ Works with huge data
❌ Noisy (zigzag path to bottom)
3. Mini-Batch Gradient Descent (Most Common!)
Use a small batch (e.g., 32 points) per step.
✅ Best of both worlds
✅ Fast AND stable
✅ Used in deep learning!
📊 Quick Comparison
Think of it like eating a giant pizza 🍕 to measure its taste:
| Type | What It Does | Analogy | Speed |
|---|---|---|---|
| Batch GD | Uses ALL 1,000,000 rows each step | Eat the WHOLE pizza to rate it | 🐢 Slow |
| Stochastic GD | Uses 1 random row each step | Taste 1 tiny bite to rate it | ⚡ Very fast (but noisy) |
| Mini-Batch GD | Uses 32 rows each step | Taste a small slice to rate it | 🚀 Best balance |
Path to minimum:
- Batch GD: Smooth, straight line to bottom (but slow per step)
- Stochastic GD: Zigzag path (fast but jumpy)
- Mini-Batch GD: Mostly smooth with tiny wiggles (winner! 🏆)
✅ When to Use Gradient Descent
| Use Gradient Descent When | Don’t Use When |
|---|---|
| ✅ Huge dataset (millions of rows) | ❌ Small dataset |
| ✅ Many features (>10,000) | ❌ Want exact answer |
| ✅ Online/streaming data | ❌ Have time for OLS |
| ✅ Complex models (neural nets) | ❌ Simple problem |
| ✅ Limited memory | ❌ Plenty of memory |
🎯 Gradient Descent Pros and Cons
Pros:
- ✅ Works with huge data (millions of rows)
- ✅ Less memory required
- ✅ Foundation of deep learning
- ✅ Online learning possible
Cons:
- ❌ Approximate solution (very close, but not exact)
- ❌ Need to tune learning rate
- ❌ May not converge if learning rate is wrong
- ❌ Slower per problem (needs many iterations)
🥊 OLS vs Gradient Descent - Side by Side
| Feature | OLS | Gradient Descent |
|---|---|---|
| How it works | Math formula | Iterative steps |
| Speed (small data) | ⚡ Super fast | 🐢 Slower |
| Speed (big data) | 🐢 Very slow | ⚡ Fast |
| Memory | High | Low |
| Accuracy | Exact | Approximate |
| Tuning needed | None | Learning rate |
| Real-world use | Sklearn LinearRegression |
Deep learning, big data |
| Analogy | Calculator | Hiking down mountain |
💡 Real-World Decision
For most beginners:
- Use sklearn’s
LinearRegression→ It uses OLS automatically! - Works perfectly for typical datasets
For big data/complex models:
- Use sklearn’s
SGDRegressor→ Uses Gradient Descent - Or move to deep learning frameworks
# Beginner choice (OLS)
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X, y) # Done! ✅
# Big data choice (Gradient Descent)
from sklearn.linear_model import SGDRegressor
model = SGDRegressor(max_iter=1000, eta0=0.01)
model.fit(X, y) # Iterates many times
🎓 Key Takeaway
Both methods find the SAME answer!
- OLS: Direct calculation (like using GPS)
- Gradient Descent: Step-by-step search (like asking for directions)
For learning, OLS is simpler. For real-world big data, Gradient Descent rules!
Simple Linear Regression (One Feature)
When to Use
- You have ONE input feature (x)
- You want to predict ONE output (y)
- The relationship appears linear
Example: Study Hours vs Test Scores
Data: | Hours Studied | Test Score | |—————|————| | 1 | 65 | | 2 | 70 | | 3 | 75 | | 4 | 80 | | 5 | 85 |
Visual:
Score
↑
100│ ●
│ ●
│ ●
│ ●
│ ●
50└────────────→ Hours
0 5 10
The Line:
Score = 60 + 5 × Hours
Interpretation:
- β₀ = 60: Base score (even with 0 hours)
- β₁ = 5: Each hour adds 5 points
- Prediction: 7 hours → 60 + 5×7 = 95 points
Multiple Linear Regression (Multiple Features)
When to Use
- You have MULTIPLE input features (x₁, x₂, x₃, …)
- You want to predict ONE output (y)
- Each feature contributes to the prediction
Example: House Price Prediction
Features:
- Size (sq ft)
- Number of bedrooms
- Age of house
- Location score
Equation:
Price = β₀ + β₁(Size) + β₂(Bedrooms) + β₃(Age) + β₄(Location)
Example Values:
Price = 50 + 0.2(Size) + 30(Bedrooms) - 1(Age) + 20(Location)
Interpretation:
- β₁ = 0.2: Each sq ft adds $200
- β₂ = 30: Each bedroom adds $30,000
- β₃ = -1: Each year older subtracts $1,000
- β₄ = 20: Better location adds $20,000
Prediction:
House: 2000 sq ft, 3 bedrooms, 10 years old, location score 8
Price = 50 + 0.2(2000) + 30(3) - 1(10) + 20(8)
= 50 + 400 + 90 - 10 + 160
= $690,000
Assumptions of Linear Regression
1. Linearity
What it means: The relationship between x and y should be linear.
How to check: Plot your data. If it looks curved, linear regression might not work well.
What to do if violated: Try polynomial regression or transform your data.
2. Independence
What it means: Each data point should be independent of others.
Example violation: Measuring the same person multiple times (not independent).
3. Homoscedasticity (Constant Variance)
What it means: The spread of errors should be consistent across all values.
Visual check: Plot errors vs predicted values. Should see random scatter, not a pattern.
4. Normality of Errors
What it means: Errors should be normally distributed.
How to check: Histogram of errors should look like a bell curve.
5. No Multicollinearity (for multiple regression)
What it means: Features shouldn’t be highly correlated with each other.
Example violation: Using both “height in inches” and “height in cm” (they’re the same thing!).
Evaluating Your Model
R-Squared (R²)
What it is: How well your line fits the data (0 to 1).
Interpretation:
- R² = 0: Model explains none of the variance (terrible)
- R² = 0.5: Model explains 50% of variance (okay)
- R² = 0.9: Model explains 90% of variance (excellent)
- R² = 1.0: Model explains all variance (perfect, but suspicious)
Formula:
R² = 1 - (Sum of squared errors / Total sum of squares)
Simple interpretation: “Percentage of variation explained by the model”
Mean Squared Error (MSE)
What it is: Average of squared errors.
Formula:
MSE = Σ(y - ŷ)² / n
Interpretation: Lower is better. Hard to interpret directly (units are squared).
Mean Absolute Error (MAE)
What it is: Average of absolute errors.
Formula:
MAE = Σ|y - ŷ| / n
Interpretation: “On average, my prediction is off by this amount”
Example: MAE = $20,000 means predictions are off by $20,000 on average.
Common Problems and Solutions
Problem 1: Overfitting
What it is: Model fits training data too well, performs poorly on new data.
Symptoms:
- Perfect R² on training data
- Terrible R² on test data
- Very complex model
Solutions:
- Use more training data
- Remove unnecessary features
- Use regularization (L1/L2)
- Try simpler model
Problem 2: Underfitting
What it is: Model is too simple, doesn’t capture patterns.
Symptoms:
- Poor R² on both training and test data
- Line doesn’t fit the data well
Solutions:
- Add more features
- Try more complex model
- Add polynomial features
- Remove outliers
Problem 3: Outliers
What it is: Extreme values that skew the line.
Visual:
y
│ ● ← outlier
│ ●
│ ●
│●
└─→ x
Solutions:
- Remove outliers (if they’re errors)
- Use robust regression
- Transform data
- Keep them if they’re real
Complete Python Example (Notebook Style)
Example 1: Simple Linear Regression
# ============================================
# SIMPLE LINEAR REGRESSION
# Predict house prices based on size
# ============================================
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error
print("🏠 HOUSE PRICE PREDICTION")
print("=" * 50)
# ============================================
# STEP 1: CREATE SAMPLE DATA
# ============================================
print("\n📊 Step 1: Creating sample data")
# House sizes (in sq ft)
X = np.array([1000, 1500, 2000, 2500, 3000, 3500, 4000]).reshape(-1, 1)
# House prices (in $1000s)
y = np.array([200, 300, 400, 500, 600, 700, 800])
print(f"Number of houses: {len(X)}")
print(f"Size range: {X.min()} - {X.max()} sq ft")
print(f"Price range: ${y.min()}k - ${y.max()}k")
# ============================================
# STEP 2: VISUALIZE THE DATA
# ============================================
print("\n📈 Step 2: Visualizing the data")
plt.figure(figsize=(10, 6))
plt.scatter(X, y, color='blue', s=100, alpha=0.7)
plt.xlabel('House Size (sq ft)')
plt.ylabel('Price ($1000s)')
plt.title('House Size vs Price')
plt.grid(True, alpha=0.3)
plt.show()
print("✅ Data plotted - can you see the linear pattern?")
# ============================================
# STEP 3: TRAIN THE MODEL
# ============================================
print("\n🤖 Step 3: Training the model")
model = LinearRegression()
model.fit(X, y)
print("✅ Model trained!")
# ============================================
# STEP 4: GET MODEL PARAMETERS
# ============================================
print("\n📋 Step 4: Model parameters")
slope = model.coef_[0]
intercept = model.intercept_
print(f"Slope (β₁): ${slope:.2f} per sq ft")
print(f"Intercept (β₀): ${intercept:.2f}")
print(f"\nEquation: Price = {intercept:.2f} + {slope:.2f} × Size")
print("\n💡 What this means:")
print(f"- A house with 0 sq ft would cost ${intercept:.2f}k (base price)")
print(f"- Each additional sq ft adds ${slope:.2f}k")
# ============================================
# STEP 5: MAKE PREDICTIONS
# ============================================
print("\n🔮 Step 5: Making predictions")
# Predict prices for our training data
y_pred = model.predict(X)
# Predict for new houses
new_sizes = np.array([1800, 2800, 3800]).reshape(-1, 1)
new_predictions = model.predict(new_sizes)
print("\nTraining data predictions:")
for i in range(len(X)):
actual = y[i]
predicted = y_pred[i]
error = actual - predicted
print(f" {X[i][0]:.0f} sq ft: ${predicted:.0f}k (actual: ${actual:.0f}k, error: ${error:.0f}k)")
print("\nNew house predictions:")
for i in range(len(new_sizes)):
size = new_sizes[i][0]
price = new_predictions[i]
print(f" {size:.0f} sq ft → ${price:.0f}k")
# ============================================
# STEP 6: EVALUATE THE MODEL
# ============================================
print("\n📊 Step 6: Model evaluation")
r2 = r2_score(y, y_pred)
mse = mean_squared_error(y, y_pred)
mae = mean_absolute_error(y, y_pred)
print(f"R² Score: {r2:.4f}")
print(f"Mean Squared Error: {mse:.2f}")
print(f"Mean Absolute Error: ${mae:.2f}k")
print("\n💡 Interpretation:")
print(f"- R² = {r2:.1%} means the model explains {r2:.1%} of the variance")
print(f"- MAE = ${mae:.0f}k means predictions are off by ${mae:.0f}k on average")
# ============================================
# STEP 7: PLOT THE REGRESSION LINE
# ============================================
print("\n📈 Step 7: Plotting the regression line")
plt.figure(figsize=(10, 6))
plt.scatter(X, y, color='blue', s=100, alpha=0.7, label='Actual data')
plt.plot(X, y_pred, color='red', linewidth=2, label='Regression line')
plt.xlabel('House Size (sq ft)')
plt.ylabel('Price ($1000s)')
plt.title('Linear Regression: House Size vs Price')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
print("✅ Regression line plotted!")
# ============================================
# STEP 8: PREDICT FOR USER INPUT
# ============================================
print("\n🎯 Step 8: Interactive prediction")
def predict_price(size):
price = model.predict([[size]])[0]
print(f"\n🏠 House size: {size} sq ft")
print(f"💰 Predicted price: ${price:.0f}k (${price*1000:.0f})")
return price
# Try it!
predict_price(2200)
predict_price(3200)
Example 2: Multiple Linear Regression
# ============================================
# MULTIPLE LINEAR REGRESSION
# Predict house prices using multiple features
# ============================================
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
print("🏠 MULTIPLE LINEAR REGRESSION")
print("=" * 50)
# ============================================
# STEP 1: CREATE SAMPLE DATA
# ============================================
print("\n📊 Step 1: Creating sample data")
# Features: Size, Bedrooms, Age, Location
X = np.array([
[1000, 2, 10, 5],
[1500, 3, 5, 7],
[2000, 3, 2, 8],
[2500, 4, 15, 6],
[3000, 4, 1, 9],
[3500, 5, 8, 8],
[4000, 5, 3, 10]
])
# Prices
y = np.array([200, 300, 400, 450, 600, 650, 800])
feature_names = ['Size (sq ft)', 'Bedrooms', 'Age (years)', 'Location (1-10)']
print(f"Number of houses: {len(X)}")
print(f"Number of features: {len(feature_names)}")
print(f"\nFeatures: {feature_names}")
# ============================================
# STEP 2: TRAIN THE MODEL
# ============================================
print("\n🤖 Step 2: Training the model")
model = LinearRegression()
model.fit(X, y)
print("✅ Model trained!")
# ============================================
# STEP 3: GET MODEL PARAMETERS
# ============================================
print("\n📋 Step 3: Model parameters")
intercept = model.intercept_
coefficients = model.coef_
print(f"Intercept (β₀): ${intercept:.2f}k")
print("\nCoefficients (β₁, β₂, β₃, β₄):")
for i, (name, coef) in enumerate(zip(feature_names, coefficients)):
print(f" {name}: ${coef:.2f}k")
print(f"\nEquation:")
print(f"Price = {intercept:.2f}", end="")
for name, coef in zip(feature_names, coefficients):
print(f" + {coef:.2f}×{name}", end="")
print()
# ============================================
# STEP 4: INTERPRET THE COEFFICIENTS
# ============================================
print("\n💡 Step 4: Interpreting coefficients")
print("What each coefficient means:")
for name, coef in zip(feature_names, coefficients):
if coef > 0:
print(f" ✓ {name}: Each unit increase adds ${abs(coef):.0f}k")
else:
print(f" ✗ {name}: Each unit increase subtracts ${abs(coef):.0f}k")
# ============================================
# STEP 5: MAKE PREDICTIONS
# ============================================
print("\n🔮 Step 5: Making predictions")
# Predict for training data
y_pred = model.predict(X)
print("\nTraining data predictions:")
for i in range(len(X)):
actual = y[i]
predicted = y_pred[i]
error = actual - predicted
print(f" House {i+1}: ${predicted:.0f}k (actual: ${actual:.0f}k, error: ${error:.0f}k)")
# Predict for new house
new_house = np.array([[2200, 3, 5, 7]])
new_prediction = model.predict(new_house)[0]
print(f"\n🏠 New house prediction:")
print(f" Size: 2200 sq ft")
print(f" Bedrooms: 3")
print(f" Age: 5 years")
print(f" Location: 7/10")
print(f" 💰 Predicted price: ${new_prediction:.0f}k")
# ============================================
# STEP 6: EVALUATE THE MODEL
# ============================================
print("\n📊 Step 6: Model evaluation")
r2 = r2_score(y, y_pred)
print(f"R² Score: {r2:.4f}")
print(f"The model explains {r2:.1%} of the variance in house prices")
Quick Reference
Key Formulas
Simple Linear Regression:
ŷ = β₀ + β₁x
Multiple Linear Regression:
ŷ = β₀ + β₁x₁ + β₂x₂ + ... + βₙxₙ
Cost Function:
Cost = Σ(y - ŷ)²
R-Squared:
R² = 1 - (SS_residual / SS_total)
Common Scikit-Learn Functions
from sklearn.linear_model import LinearRegression
# Create model
model = LinearRegression()
# Train model
model.fit(X_train, y_train)
# Make predictions
y_pred = model.predict(X_test)
# Get parameters
intercept = model.intercept_
coefficients = model.coef_
# Evaluate
from sklearn.metrics import r2_score, mean_squared_error
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
When to Use Linear Regression
✅ Good For:
- Predicting continuous values (prices, temperatures, scores)
- When relationship appears linear
- When you want interpretable results
- When you have enough data (50+ points preferred)
- When assumptions are met
❌ Not Good For:
- Classifying into categories (use classification)
- When relationship is clearly non-linear
- When you have very little data (< 20 points)
- When features are highly correlated
- When you need perfect accuracy
Next Steps
Practice Ideas:
- Predict car prices from mileage, age, brand
- Predict student grades from study hours, attendance
- Predict salary from experience, education, location
- Predict sales from advertising spend, season, price
Advanced Topics:
- Polynomial Regression (for curved relationships)
- Ridge/Lasso Regression (for regularization)
- Logistic Regression (for classification)
- Generalized Linear Models
Summary
Linear Regression is:
- ✅ Simple and interpretable
- ✅ Fast to train
- ✅ Good baseline model
- ✅ Great for understanding relationships
- ✅ Foundation for more complex models
Key Takeaways:
- Find the best line through your data
- Use slope and intercept to make predictions
- Evaluate with R², MSE, MAE
- Check assumptions
- Start simple, then improve
Remember: Linear Regression is the “Hello World” of machine learning. Master it first, then move to more complex algorithms! 🚀
Happy Learning! 📚