Build Your First Linear Regression

Build your first linear regression model in Python — learn the core steps, hands-on code, common pitfalls, and what to study next in the Applied AI engineering track.

Focus: build your first linear regression model

Sponsored

You've probably heard that linear regression is the 'hello world' of machine learning, but when you actually sit down to build your first model, you quickly realize the gap between a 30-second YouTube explanation and a real, working pipeline. Data arrives messy, features need scaling, and a single NaN can silently ruin every prediction you make. This lesson removes that friction: by the end, you'll have built, trained, and evaluated your first linear regression model in Python — with code you can adapt to your own datasets and a clear mental model that makes every future ML algorithm easier to grasp.

The problem this lesson solves

Most tutorials show you a scatter plot and three lines of sklearn code, then declare victory. That approach leaves you stranded when you try to apply linear regression to a real dataset. The actual pain points:

  • Your data is never clean. Real-world CSV files contain missing values, outliers, and columns measured in wildly different units (e.g., square footage vs. number of bedrooms).
  • A single wrong assumption breaks predictions. Linear regression assumes a linear relationship and independent errors — if you ignore those, your model looks fine in training but fails in production.
  • Evaluation is ambiguous. The R² score alone doesn't tell you if your model is useful — you need residuals, MSE, and domain context.

This lesson solves exactly that by walking you through a complete pipeline: data preparation → model training → evaluation → interpretation. You'll learn not just the fit() call, but why each piece matters and how to debug when things go wrong.

Core concept / mental model

Think of linear regression as a best-fit line through a cloud of points. The model learns two numbers: the intercept (where the line crosses the y-axis) and the coefficient (how steep the line is). The line itself is your prediction function:

y_pred = intercept + coefficient * x

For multiple features, it becomes a hyperplane: y = b0 + b1*x1 + b2*x2 + ... + bn*xn. The algorithm finds the values of b that minimize the sum of squared errors — the vertical distances between each actual point and the line.

The key assumption

The most important mental model is that linear regression assumes a linear relationship between inputs and output. If your data is curved (like exponential growth), a straight line will underfit. That's why the first step of any regression task is always data exploration — plot your features against the target before training.

Pro tip: Linear regression is like fitting a ruler to data. It's fast, interpretable, and surprisingly powerful — but it can't bend. If your data needs a curve, you need polynomial features (covered later in this track).

How it works step by step

Building a linear regression model follows the same pattern as any sklearn model. Here's the ordered sequence:

  1. Load and inspect the data — Understand its shape, column types, and target distribution.
  2. Split into features (X) and target (y) — The target is what you're predicting; features are what you predict from.
  3. Split into training and test sets — Always keep a holdout set to measure real performance on unseen data. Use train_test_split with a fixed random seed for reproducibility.
  4. Preprocess the data (if needed) — Linear regression is sensitive to feature scales, so standardization helps coefficients converge and makes them interpretable. Missing values must be cleaned or imputed.
  5. Train the modelLinearRegression().fit(X_train, y_train) finds optimal coefficients.
  6. Evaluate — Compute metrics like Mean Squared Error (MSE) and R² on both train and test sets. Compare them — a gap indicates overfitting.
  7. Interpret and iterate — Look at residuals (prediction errors) to spot non-linearity or heteroscedasticity.

Why split at all?

If you train and evaluate on the same data, the model can memorize noise instead of learning patterns. A held-out test set simulates how the model will behave on new, unseen data — that's what matters in production.

Hands-on walkthrough

Let's build a model that predicts house prices from a single feature: square footage. We'll generate synthetic data (so you can see exactly how the pipeline works), then you can swap in your own CSV later.

Step 1: Setup and data generation

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# Generate a synthetic dataset with 200 samples, 1 feature
X, y, coef = make_regression(n_samples=200, n_features=1, noise=10, coef=True, random_state=42)

# Convert to a pandas DataFrame for convenience (optional but realistic)
df = pd.DataFrame({'sq_footage': X[:, 0], 'price': y})
print(df.head())
print(df.describe())

Expected output:

   sq_footage      price
0    0.496714  12.416520
1   -0.138264  -2.407629
2    0.647689  25.738552
3    1.523030  58.517680
4   -0.234136  -7.313628

       sq_footage      price
count   200.00000  200.00000
mean      0.00577    0.18707
std       0.97998   11.55852
min      -3.24126  -36.43304
25%      -0.65510   -7.62336
50%       0.00709    0.62006
75%       0.64562    8.55494
max       3.11729   38.08979

Step 2: Split and train

# Split into training and test sets (80/20)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Create and train the model
model = LinearRegression()
model.fit(X_train, y_train)

# Print learned parameters
print(f"Intercept: {model.intercept_:.2f}")
print(f"Coefficient (slope): {model.coef_[0]:.2f}")

Expected output (varies slightly due to noise):

Intercept: -0.93
Coefficient (slope): 38.85

This means the model learned: price ≈ -0.93 + 38.85 * sq_footage. The coefficient tells you that each one-unit increase in square footage adds roughly $38.85 to the predicted price.

Step 3: Evaluate performance

# Predict on test set
predictions = model.predict(X_test)

# Calculate metrics
mse = mean_squared_error(y_test, predictions)
r2 = r2_score(y_test, predictions)

print(f"Mean Squared Error: {mse:.2f}")
print(f"R² Score: {r2:.4f}")

# Visualize fit
plt.scatter(X_test, y_test, alpha=0.5, label='Actual')
plt.scatter(X_test, predictions, alpha=0.5, color='red', label='Predicted')
plt.xlabel('Square footage')
plt.ylabel('Price')
plt.legend()
plt.title('Linear Regression Fit')
plt.show()

Expected output (values will vary):

Mean Squared Error: 117.86
R² Score: 0.8356

An R² of ~0.84 means that about 84% of the variance in price is explained by square footage alone — which is good for a single feature. The MSE of ~118 is the average squared error; for interpretability, take the square root to get the typical error in price units (≈$10.9).

Pro tip: Always report RMSE (root-mean-squared-error) in the same units as your target, not raw MSE. It's far more intuitive to say "our predictions are off by ~$11 on average" than "MSE is 118."

Compare options / when to choose what

You rarely have to write the math yourself — know which tool to reach for:

Option When to use Pros Cons Python implementation
sklearn.linear_model.LinearRegression Most standard use cases Simple, interpretable, fast Assumes linearity, sensitive to outliers LinearRegression().fit(X, y)
statsmodels.OLS When you need statistical inference (p-values, confidence intervals) Rich stats output More verbose sm.OLS(y, X).fit()
Gradient descent (manual) Learning purposes / large datasets Full control, scalable Requires tuning learning rate Custom loop in NumPy
Polynomial regression Non-linear relationships Captures curves Risk of overfitting PolynomialFeatures transform + LinearRegression

How to choose: For 90% of applied problems, start with LinearRegression and check residuals. Only if you need hypothesis testing (e.g., "Is this coefficient statistically significant?") switch to statsmodels. If you see a curved pattern in residuals, explore polynomial regression — but beware of overfitting as you add degrees.

Troubleshooting & edge cases

Even seasoned engineers hit these issues. Here's how to identify and fix them:

  • R² is negative on test set. This usually means severe overfitting or a bad train/test split. Check that you haven't accidentally included the target as a feature. Also verify that the test set is representative of the training distribution.
  • Coefficients are huge or tiny. This is a classic sign of features with different scales. Standardize your features using StandardScaler before fitting. For example, if one feature is in square footage and another in number of rooms, the coefficient magnitudes will differ wildly — making them impossible to compare.
  • NaN values in the data. LinearRegression silently fails or throws an error. Use df.dropna() or SimpleImputer to handle missing values before splitting. Run df.isna().sum() to find them.
  • Predictions are constant. If your target doesn't vary, or all features are zero, the model predicts the mean. Check the variance of your target and features.
  • Outliers skew the line. Linear regression is sensitive to outliers because squared errors amplify their impact. Plot your data first; if you see extreme points, consider robust regression (like RANSAC) or remove them if they're truly erroneous.
  • The ZeroDivisionError when scaling. This happens if a feature has zero variance (all identical values). Remove such constants or add a tiny epsilon.

What you learned & what's next

You can now confidently build your first linear regression model in Python. Specifically, you've learned:

  • The mental model of linear regression as a best-fit line that minimizes squared errors.
  • The step‑by‑step pipeline: load → split → preprocess → train → evaluate → interpret.
  • How to compare tools (sklearn vs. statsmodels vs. gradient descent) and when to pick which.
  • How to troubleshoot common issues like feature scaling, missing values, and negative R².

This foundational skill sets you up for the next lesson in the Applied AI engineering track: polynomial regression and feature engineering. There, you'll learn how to handle non-linear relationships while keeping the same model family — and how feature transformations can dramatically improve performance without changing your core workflow.

Everything you built here forms the evaluation harness pattern you'll reuse in later lessons on regression diagnostics and model selection. Practice now: download a real dataset (like the Boston Housing dataset, though it's deprecated — use California Housing), build a multi-feature regression, and observe how the coefficient interpretation changes.

Practice recap

Grab a real dataset (e.g., California housing from sklearn.datasets.fetch_california_housing), and build a linear regression predicting median house value. Visualize the residuals after fitting. If you see a funnel shape, try applying a log-transform to the target and refit — observe how RMSE changes. Then, note the coefficient of square footage vs. number of rooms to build intuition about feature scaling.

Common mistakes

  • Forgetting to split data before training — evaluating on the training set gives a falsely high R² and hides overfitting.
  • Not checking for missing values — a NaN in your features silently makes fit fail or produces nonsense coefficients.
  • Ignoring feature scales — mixing square footage (thousands) with number of bedrooms (single digits) makes coefficients uninterpretable and can slow convergence.
  • Using R² alone — a high R² doesn't guarantee the model is good; always inspect residual plots and RMSE to catch non-linearity or outliers.
  • Misinterpreting the intercept — it's the predicted value when all features are zero, which may be meaningless in real-world contexts.

Variations

  1. Use statsmodels instead of sklearn when you need p-values, confidence intervals, and detailed hypothesis tests for your coefficients.
  2. Implement a simple gradient descent loop in NumPy to see how the optimization works under the hood — great for building intuition.
  3. Try polynomial regression by adding PolynomialFeatures to capture curved relationships while keeping the same linear model framework.

Real-world use cases

  • Predicting house prices from features like square footage, number of bedrooms, and location for a real estate analytics dashboard.
  • Estimating a product's sales volume based on advertising spend across channels (TV, radio, online) to optimize budget allocation for a marketing team.
  • Forecasting an employee's annual salary from years of experience and education level to guide HR compensation decisions.

Key takeaways

  • Linear regression finds the line that minimizes squared errors — its power lies in simplicity and interpretability.
  • Split your data into train/test sets before any preprocessing to simulate real-world performance.
  • Scale your features when they have different units; otherwise coefficients lose meaning and optimization slows.
  • Use RMSE for error reporting (same units as target) and residual plots to validate assumptions — R² alone is not enough.
  • Choose sklearn for quick pipelines, statsmodels for statistical inference, and polynomial regression to handle curves.
  • Troubleshoot systematically: check for NaNs, outliers, and constant features before doubt your model code.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.