A Step-by-Step Tutorial on Polynomial Regression in Python

Ujang Riswanto
16 min readOct 28, 2024

--

Photo by Zach Graves on Unsplash

What is Polynomial Regression?

When working with data, you might start with linear regression to model the relationship between variables — basically drawing a straight line that fits your data. But what if your data just doesn’t follow a straight path? That’s where polynomial regression comes in.

Polynomial regression is like giving your model a little more flexibility. Instead of fitting just a straight line, it fits curves by adding powers to your input features (like squares, cubes, and so on). Imagine a scatter plot with a clear curve, maybe something like tracking the speed of a falling object over time — it’s not linear, but it follows a pattern that bends. Polynomial regression can capture these kinds of trends way better than a simple line.

Why Use Polynomial Regression?

Here are a few real-world scenarios where polynomial regression can shine:

  • Predicting housing prices: Sometimes house prices don’t increase linearly with square footage. There might be a curve to that trend.
  • Modeling growth patterns: Think about plant growth, where things start slow, grow fast, and then plateau — again, not a straight line.
  • Forecasting demand: In economics or retail, demand might increase sharply at first, peak, and then decline, forming an arc-like trend.

In short, if your data isn’t cooperating with a straight-line approach, polynomial regression offers a way to model the curves in the relationship.

What This Tutorial Will Cover

In this tutorial, we’ll walk through how to implement polynomial regression in Python step by step. You’ll learn how to:

  1. Prepare the data: Get everything set up to feed into the model.
  2. Transform features: Expand your data to include polynomial terms.
  3. Train the model: Use Scikit-learn to fit your polynomial regression.
  4. Evaluate performance: See how well your curve matches reality.
  5. Optimize the model: Tweak the degree of the polynomial to avoid overfitting or underfitting.

By the end of this tutorial, you’ll not only know how to use polynomial regression but also understand when it makes sense to use it — and when it’s better to explore other models. Let’s dive in!

Prerequisites

Photo by Firmbee.com on Unsplash

Before we jump into the fun part — coding and curve-fitting — let’s make sure you’ve got everything you need to follow along smoothly. Don’t worry, it’s not too complicated!

What You Should Know

You don’t need to be a data science wizard to get through this tutorial, but having a bit of background in these areas will help:

  • Python Basics: You should be comfortable writing and running Python code. (If you know how to use print() and loops, you’re good!)
  • Linear Regression: A basic idea of how linear regression works would be helpful since polynomial regression builds on it.
  • Familiarity with Libraries: If you’ve dabbled with NumPy, Pandas, or Matplotlib before, that’s awesome. We’ll use them to handle data and make nice-looking plots.

Even if these are new to you, don’t worry — we’ll walk through the code step by step!

Tools and Libraries You’ll Need

We’ll use some common Python libraries throughout the tutorial. Here’s the lineup:

  1. NumPy — For numerical operations (think math stuff like arrays and calculations).
  2. Pandas — Helps with organizing and manipulating data (think spreadsheets but in Python).
  3. Scikit-learn — This is the star of the show for machine learning tasks like regression.
  4. Matplotlib & Seaborn — These will make our graphs look neat and visually pleasing.

If you don’t have these installed, no big deal. Just open up your terminal or command prompt and run:

pip install numpy pandas scikit-learn matplotlib seaborn

If you’re using Jupyter Notebooks or Google Colab, you can also install directly in a notebook cell like this:

!pip install numpy pandas scikit-learn matplotlib seaborn

Optional: Jupyter Notebooks

If you like interactive coding, Jupyter Notebooks are a great way to experiment. You can write code in chunks, see the output right below it, and tweak things as you go. If you want to try it out, just install Jupyter with:

pip install notebook

Then, run this in your terminal:

jupyter notebook

This will open a notebook in your browser, where you can write and run Python code easily.

With these tools ready, you’ll have everything set up to dive into polynomial regression like a pro. Let’s move on to the dataset prep! 🚀

Setting Up the Environment

Photo by Lavi Perchik on Unsplash

Alright, now that you know what we’re going to do and the tools we’ll use, it’s time to get everything ready to roll. Don’t worry — it’s just a few steps, and you’ll be coding in no time. Let’s get your environment set up!

Step 1: Install the Necessary Libraries

If you don’t already have the libraries installed, open up your terminal (or command prompt) and run this command:

pip install numpy pandas scikit-learn matplotlib seaborn

This will install all the tools we need for working with data, building models, and making beautiful plots. If you’re using Google Colab, you can run the same command right inside a notebook by adding an exclamation mark (!) at the start:

!pip install numpy pandas scikit-learn matplotlib seaborn

💡 Pro tip: If you’re not sure whether a library is installed, just try importing it in your code. If there’s no error, you’re good to go!

Step 2: Optional but Fun — Use Jupyter Notebooks

If you want to experiment with the code and see results step by step, Jupyter Notebooks are awesome. They let you write code in small chunks (called cells), run it one piece at a time, and see the output right away.

To install Jupyter, just run:

pip install notebook

Once installed, launch a notebook with:

jupyter notebook

This will open a new tab in your browser where you can create a notebook and get coding! If you’ve never used Jupyter before, don’t worry — it’s super easy, and you’ll pick it up fast.

Step 3: Check Your Python Setup

Make sure you’ve got Python installed on your machine. If you’re not sure, open a terminal and type:

python --version

If it prints out a version number, you’re good to go! If not, head over to Python’s official site to download and install it.

Step 4: Choose Your Code Editor

You can write the code for this tutorial in:

  • Jupyter Notebooks (for interactive coding)
  • Google Colab (great if you don’t want to install anything)
  • VS Code, PyCharm, or any text editor

If you go with Colab, just visit colab.research.google.com and start a new notebook — everything will be pre-installed for you!

That’s it! 🎉 Now that you’ve got your environment set up, we’re ready to dive into the fun stuff: working with data and building your polynomial regression model. Let’s keep going!

Preparing the Dataset

Photo by Clay Banks on Unsplash

Time to get our hands dirty with some data! 🧑‍💻 Before we can build a polynomial regression model, we need a dataset to work with. In this section, we’ll either use a built-in dataset or generate some custom data. Plus, we’ll do a bit of data exploration to understand what we’re working with. Let’s dive in!

Step 1: Choose or Create a Dataset

You’ve got two options here:

  1. Use a Sample Dataset: We can grab a dataset from Scikit-learn or load one from a CSV file. For this tutorial, we’ll use the make_regression() function from Scikit-learn to generate some synthetic data. We’ll spice it up by adding a non-linear twist.
  2. Generate Synthetic Data with Curves: This is great if you want more control over the shape of your data. Here’s how you can create some wavy, polynomial-like data using NumPy.

Example: Generate Curved Data with NumPy:

import numpy as np
import matplotlib.pyplot as plt

# Generate some data points
np.random.seed(42) # For reproducibility
X = np.random.rand(100, 1) * 10 # Random values between 0 and 10
y = 2 + 0.5 * X**2 + np.random.randn(100, 1) * 3 # Quadratic relationship with noise

# Plot the data
plt.scatter(X, y, color='blue', label='Data Points')
plt.xlabel('X')
plt.ylabel('y')
plt.title('Generated Data with Polynomial Pattern')
plt.legend()
plt.show()

This snippet generates 100 data points following a quadratic pattern. You’ll notice that the scatter plot forms a curve, making it perfect for polynomial regression.

Step 2: Load a Dataset (If Using CSV)

If you’d rather use real-world data from a CSV, here’s how to load it using Pandas:

import pandas as pd

# Load dataset from a CSV file
data = pd.read_csv('your-dataset.csv')
print(data.head()) # Display the first few rows

Just replace 'your-dataset.csv' with the path to your file, and Pandas will read it for you. If your data has a clear non-linear trend, great! If not, you can still experiment with polynomial regression to see if it improves the fit.

Step 3: Explore the Data (EDA)

Before we jump into modeling, let’s do a bit of exploratory data analysis (EDA) to understand our dataset. Here’s a checklist of things we’ll want to do:

  • Look at summary statistics: Get a sense of the data range and distribution.
  • Visualize relationships: Plot the features against the target to see if we spot any patterns.

Example: Quick EDA

# Summary statistics
print(data.describe())

# Visualize the relationship between X and y
plt.scatter(data['X'], data['y'], color='green', label='Data Points')
plt.xlabel('X')
plt.ylabel('y')
plt.title('EDA: Relationship Between X and y')
plt.legend()
plt.show()

From the plots, you’ll be able to tell whether your data has a polynomial pattern. If it looks like a curve instead of a straight line, you’re on the right track for polynomial regression.

Step 4: Split the Data for Training and Testing

To make sure our model works well, we need to split the data into two parts:

  • Training data: Used to fit the model.
  • Testing data: Used to check how well the model performs on unseen data.

Here’s how to do it using Scikit-learn:

from sklearn.model_selection import train_test_split

# Split the data (80% training, 20% testing)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

print(f'Training data size: {X_train.shape[0]}')
print(f'Test data size: {X_test.shape[0]}')

With the data prepared, explored, and split, we’re all set to start transforming it for polynomial regression. Next stop: feature transformation! 🚀

Transforming Data for Polynomial Regression

Photo by Markus Spiske on Unsplash

Alright! We’ve got our data prepped and ready, but here’s the thing: polynomial regression isn’t going to magically understand those curved relationships unless we give it a little help. That’s where feature transformation comes in. In this section, we’ll break down how to turn your data into something your model can actually use to fit curves.

Step 1: What Are Polynomial Features?

In regular linear regression, we use the original input features (like X) to find a straight-line relationship. But for polynomial regression, we need to create extra features by raising X to different powers. For example:

If X=[1,2,3], adding polynomial features (degree 2) transforms it to:
[1, 1²], [2, 2²], [3, 3²]
So it becomes:
[1,1],[2,4],[3,9]

This way, we give our model more information to work with. The higher the degree of the polynomial, the more complex the curve it can fit.

Step 2: Use Scikit-learn’s PolynomialFeatures to Transform the Data

Luckily, Scikit-learn makes this super easy. It has a built-in class called PolynomialFeatures that handles all the math for us. Let’s see how it works.

Example: Creating Polynomial Features

from sklearn.preprocessing import PolynomialFeatures

# Create a PolynomialFeatures object (degree 2)
poly = PolynomialFeatures(degree=2, include_bias=False)

# Transform the original X values
X_train_poly = poly.fit_transform(X_train)
X_test_poly = poly.transform(X_test) # Use the same transformation on test data

print(f'Original X shape: {X_train.shape}')
print(f'X after transformation: {X_train_poly.shape}')

What’s happening here? 👀

  • We create a PolynomialFeatures object with degree=2. You can change the degree if you need a more complex curve.
  • fit_transform() takes the original X_train and transforms it to include polynomial terms (like xxx and x2x^2x2).
  • We also apply the same transformation to X_test to make sure both sets are consistent.

Step 3: Check Out the Transformed Data

Curious to see what your transformed data looks like? Let’s print the first few rows!

print(X_train_poly[:5])  # Display the first 5 transformed rows

If you used degree 2, you’ll notice that each row now has two columns: one for the original X and one for X^2. If you set a higher degree (like 3), you’d get even more columns, such as X, X^2X2, and X^3.

Step 4: When to Stop Adding Degrees?

You might wonder: Why not keep adding more degrees? Won’t a higher degree fit the data better?
Well, yes and no. If you add too many polynomial terms, you run the risk of overfitting — meaning your model becomes too good at fitting the training data but fails on new data. So, it’s all about finding the right balance. We’ll explore this more in the optimization section later on.

Now that our data is transformed with polynomial features, we’re ready to fit it into a model and see how well it performs. 🚀 Next step: training the polynomial regression model! Let’s go!

Training the Polynomial Regression Model

Photo by Luke Chesser on Unsplash

Alright, the moment we’ve been waiting for! 🎉 Now that our data is transformed with polynomial features, it’s time to build and train our model. This part is super satisfying because, by the end, we’ll see how well our polynomial curve fits the data. Let’s get into it!

Step 1: Import the Linear Regression Model

Polynomial regression sounds fancy, but it’s really just linear regression applied to polynomial features. So, we’ll use Scikit-learn’s LinearRegression class to fit our transformed data. Here’s how:

from sklearn.linear_model import LinearRegression

# Create the LinearRegression model
model = LinearRegression()

Nothing too tricky here. We’re setting up a plain linear regression model that will soon handle our polynomial data.

Step 2: Train the Model on the Training Data

Now let’s fit the model to our polynomial-transformed data. We use the transformed X_train_poly as input and y_train as the target.

# Train the model on polynomial features
model.fit(X_train_poly, y_train)

# Print the model’s coefficients and intercept
print(f"Intercept: {model.intercept_}")
print(f"Coefficients: {model.coef_}")

When you run this, you’ll see the intercept and coefficients of your model. These values tell you the equation of the fitted curve (though we’re more interested in the plot than the math right now!).

Step 3: Make Predictions on Test Data

Now that the model is trained, let’s see how well it does on the test data. We’ll use the transformed X_test_poly to make predictions.

# Predict using the test data
y_pred = model.predict(X_test_poly)

# Print the first few predictions
print(f"Predicted values: {y_pred[:5]}")

We’ve got predictions! 🎯 Now, let’s visualize how well the model’s curve matches the actual data.

Step 4: Visualize the Model’s Fit

This part is fun. We’ll plot both the original data points and the fitted curve to see how well the model captured the trend.

import matplotlib.pyplot as plt

# Scatter plot of original test data
plt.scatter(X_test, y_test, color='blue', label='Actual Data')

# Line plot of the model’s predictions
plt.plot(X_test, y_pred, color='red', label='Fitted Curve', linewidth=2)

plt.xlabel('X')
plt.ylabel('y')
plt.title('Polynomial Regression: Actual vs Predicted')
plt.legend()
plt.show()

If everything went well, you’ll see a red curve that hugs your data points nicely. How well the curve fits depends on the degree you used earlier — too low, and it might not catch the curve; too high, and it could overfit.

Step 5: Evaluate the Model’s Performance

Finally, let’s check how well our model performs using some metrics. We’ll use mean squared error (MSE) and R² score to evaluate the fit.

from sklearn.metrics import mean_squared_error, r2_score

# Calculate MSE and R² score
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f"Mean Squared Error: {mse:.2f}")
print(f"R² Score: {r2:.2f}")
  • MSE: Measures how far off the predictions are from the actual values (lower is better).
  • R² Score: Tells you how well the model explains the variation in the data (closer to 1 is better).

And that’s it! 🎉 You just trained a polynomial regression model, made predictions, and evaluated how well it performs. If the results aren’t quite what you expected, don’t worry — we’ll tweak and optimize the model in the next section to get the best fit possible. Let’s keep going! 🚀

Evaluating and Fine-Tuning the Model

Photo by Scott Graham on Unsplash

Nice job — your polynomial regression model is up and running! 🎉 Now comes an important part: evaluating how well it performs and tweaking it for better results. Just like seasoning a dish, you sometimes need to adjust things until the model tastes just right. Let’s walk through how to measure performance and fine-tune your model like a pro.

Step 1: Evaluate with Key Metrics

First things first, let’s make sure our model isn’t just guessing randomly. The two main metrics we’ll focus on are:

  • Mean Squared Error (MSE): Measures how far off our predictions are from actual values (lower is better).
  • R² Score: Tells us how well the model explains the variation in the data (closer to 1 means the model is killing it).

Here’s a quick recap of the code from the last section:

from sklearn.metrics import mean_squared_error, r2_score

# Evaluate the model's predictions
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

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

If your R² score is close to 1, congrats! Your model is doing great. If it’s way off or negative, don’t panic — we’ll talk about ways to fix that next.

Step 2: Try Different Polynomial Degrees

Sometimes, your curve is either too simple (underfitting) or way too complicated (overfitting). The degree of the polynomial can make a big difference. A degree that’s too low might miss important patterns, while a degree that’s too high might fit the noise in the data.

Example: Experiment with Degree 3 or Higher

# Try polynomial features with a higher degree
poly = PolynomialFeatures(degree=3, include_bias=False)
X_train_poly = poly.fit_transform(X_train)
X_test_poly = poly.transform(X_test)

# Retrain the model with the new features
model.fit(X_train_poly, y_train)

# Make new predictions
y_pred = model.predict(X_test_poly)

Try a few different degrees and see which one gives the best fit. If the MSE decreases and R² improves, you’re on the right track!

Step 3: Use Cross-Validation for a Robust Model

To make sure your model isn’t overfitting, you can use cross-validation. This technique splits the data into multiple subsets, trains the model on some, and tests it on others. It’s a great way to ensure your model works well across different data points.

from sklearn.model_selection import cross_val_score

# Perform 5-fold cross-validation
cv_scores = cross_val_score(model, X_train_poly, y_train, cv=5, scoring='r2')

print(f"Cross-Validation R² Scores: {cv_scores}")
print(f"Average R² Score: {cv_scores.mean():.2f}")

If your cross-validation scores look consistent, you can be more confident in your model’s performance.

Step 4: Regularization to Avoid Overfitting

If your model fits the training data too perfectly but flops on the test data, you might be overfitting. To fix this, you can try regularization techniques like Ridge or Lasso regression, which penalize overly complex models.

Example: Ridge Regression

from sklearn.linear_model import Ridge

# Create and train a Ridge regression model
ridge_model = Ridge(alpha=1.0)
ridge_model.fit(X_train_poly, y_train)

# Make predictions and evaluate
y_pred_ridge = ridge_model.predict(X_test_poly)
r2_ridge = r2_score(y_test, y_pred_ridge)

print(f"R² Score with Ridge Regression: {r2_ridge:.2f}")

Regularization keeps the model’s complexity in check and helps it generalize better to unseen data.

Step 5: Visualize the Impact of Tuning

Seeing the results of your adjustments is always satisfying. Let’s visualize how your changes (like using a higher degree or regularization) impact the curve.

# Plot original test data
plt.scatter(X_test, y_test, color='blue', label='Actual Data')

# Plot predictions from the tuned model
plt.plot(X_test, y_pred, color='red', label='Tuned Model', linewidth=2)

plt.xlabel('X')
plt.ylabel('y')
plt.title('Tuned Polynomial Regression: Actual vs Predicted')
plt.legend()
plt.show()

A well-tuned model should show a nice curve that hugs the data points without overfitting.

Step 6: Final Thoughts

Model tuning is part art, part science. If your first model doesn’t perform as well as you hoped, don’t stress — this is normal. Experiment with different polynomial degrees, try cross-validation, and use regularization when needed.

The goal is to strike a balance: a model that fits the data well without being too complicated. With a bit of trial and error, you’ll get there! 🚀

That’s it for fine-tuning! Now you’ve got a polished polynomial regression model that can handle those tricky curves. Up next: wrapping everything up and adding some final thoughts. You’re almost there! 🎉

Wrapping It All Up

Boom! 🎉 You’ve made it through an entire polynomial regression project from start to finish. Let’s quickly recap what we’ve done, reflect on key takeaways, and talk about some ideas for what you could try next. Spoiler alert: You’re now equipped to tackle way more than just straight lines!

What We Covered

Here’s a quick summary of everything you accomplished:

  1. Introduced Polynomial Regression: We learned how it extends linear regression to handle curved relationships.
  2. Set Up the Python Environment: Installed the necessary libraries to build our model.
  3. Explored and Prepared the Dataset: We either generated data with a polynomial pattern or loaded it from a CSV.
  4. Transformed Features: We used PolynomialFeatures to create new features from the original ones.
  5. Trained the Model: Built a regression model and fit it to the transformed data.
  6. Evaluated the Model: Measured performance using MSE and R², and visualized the curve.
  7. Fine-Tuned the Model: Tried different polynomial degrees, used cross-validation, and explored regularization to avoid overfitting.

Pretty awesome, right? 🚀 You’ve essentially unlocked a new level of data science skills!

Key Takeaways

  1. Polynomial Regression is Powerful, but…
    It’s great for capturing curves, but too many degrees can lead to overfitting. Always keep an eye on your evaluation metrics and use tools like cross-validation to stay on track.
  2. Experimenting is Key
    Don’t be afraid to tweak the degree of your polynomial or try out Ridge and Lasso regularization. Every dataset is unique, and a little trial-and-error will help you get the best results.
  3. Visualizations Help a Lot
    Seeing the curve fit the data points makes it easier to understand how well your model is performing. Plots are your best friend when working with regression models.

What’s Next?

Now that you’ve got polynomial regression under your belt, here are a few things you could try next:

  • Try Higher-Dimensional Data: Use datasets with multiple features to explore multivariate polynomial regression.
  • Play with Real-World Data: Find a dataset on Kaggle or UCI Machine Learning Repository that has non-linear patterns and apply what you’ve learned.
  • Compare with Other Models: Try models like decision trees or random forests to see how they compare with polynomial regression on your dataset.
  • Build a Polynomial Regression Web App: If you’re feeling adventurous, use Streamlit or Flask to build a simple app where users can upload data and fit polynomial models interactively.

Final Thoughts

Polynomial regression is a great tool when your data isn’t playing nice with a straight line. Now that you know how to handle curves, you’re in a great spot to tackle more complex data science challenges. Just remember: the goal is to model the real-world patterns without overcomplicating things.

Thanks for sticking with me through this tutorial! 🎉 I hope you had fun and feel confident about using polynomial regression in your future projects. The data science world is full of challenges, but with skills like these, you’re more than ready to dive in.

And that’s a wrap! 👏 Happy coding and good luck on your next project! 🚀

--

--

Ujang Riswanto
Ujang Riswanto

Written by Ujang Riswanto

web developer, uiux enthusiast and currently learning about artificial intelligence

No responses yet