Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 72

Preprocessing and Feature Engineering on Raw Data

Recommended resources

Welcome to your final project module. In our last lesson, you developed a strategic framework for selecting the right machine learning algorithm. This involved asking critical questions about your problem type, data characteristics, and project constraints. Now, we shift from strategy to execution. Before we can test different algorithms, we need to build the "factory" that will prepare our raw data for modeling.

This lesson focuses on a crucial engineering practice in machine learning: executing a full preprocessing and feature engineering pipeline on a raw dataset. You'll learn how to chain together all the steps you've mastered—imputation, encoding, scaling, and feature creation—into a single, robust, and reproducible object using scikit-learn. Given your background in software development and building CI/CD pipelines for web applications, the concept of creating a streamlined, automated workflow for data should feel both familiar and powerful.

Why Bother with Pipelines?

You might wonder why we can't just run our preprocessing steps one by one in a Jupyter notebook. While that's fine for initial exploration, it's inefficient and prone to errors in a real project. Machine learning pipelines offer several key advantages that are critical for professional work.

The following short video provides an excellent overview of these benefits.

Building a Machine Learning Pipeline with Python and Scikit-Learn | Step-by-Step Tutorial

This video from the Ryan & Matt Data Science channel introduces the core motivations for using pipelines in a machine learning workflow.

Please watch the introduction which outlines three main advantages: preventing data leakage, reusability, and organizing your workflow.

As the video highlights, the key benefits are:

  1. Preventing Data Leakage: This is the most critical advantage. When you preprocess your entire dataset before splitting it into training and testing sets, information from the test set (like its mean or variance for scaling) "leaks" into the training process. This can lead to an optimistically biased performance estimate. Pipelines ensure that transformations are fit only on the training data and then applied to both the training and test data, mimicking a real-world scenario.
  2. Simplicity and Organization: A pipeline encapsulates many steps into a single object. Instead of calling fit_transform on your imputer, then your scaler, then your encoder, you just call .fit() once on the pipeline. This makes your code cleaner and less error-prone.
  3. Reproducibility and Deployment: A single pipeline object can be easily saved and reloaded. This is essential for deploying your model in a production environment, where you need to apply the exact same sequence of transformations to new, incoming data.

The Anatomy of a Scikit-learn Pipeline

In scikit-learn, a comprehensive preprocessing pipeline is typically built from two main components: Pipeline and ColumnTransformer.

  • Pipeline: This object chains together multiple processing steps that are applied sequentially to the same set of data (e.g., impute missing values, then scale the data).
  • ColumnTransformer: This object is used when you have mixed data types (e.g., numerical and categorical columns) and need to apply different processing steps to different columns in parallel.

The ColumnTransformer is the heart of most modern preprocessing pipelines. It allows you to specify, for instance, that numerical columns should be imputed and scaled, while categorical columns should be imputed and one-hot encoded. The results are then automatically combined back into a single feature matrix.

This diagram illustrates how a `ColumnTransformer` directs different types of features (numeric, categorical, custom) into separate preprocessing branches before they are combined and fed into a final model. This parallel processing is key to handling real-world datasets.

Building a Pipeline: From Simple to Complex

Let's see how these components are used in practice. We'll start with a simple pipeline and then build up to a more realistic, complex one.

A Basic Pipeline for a Single Data Type

If all your features were numerical, you could use a simple Pipeline to chain your preprocessing steps. The video you just started offers a clear, step-by-step tutorial for this exact scenario.

Building a Machine Learning Pipeline with Python and Scikit-Learn | Step-by-Step Tutorial

This section of the video demonstrates how to build a basic pipeline for numerical data using make_pipeline.

Watch the segment from "add in an imputer". Pay attention to how a SimpleImputer and a LogisticRegression model are combined into a single pipe1 object using make_pipeline, and how .fit() is then called just once on the training data.

The video uses make_pipeline, which is a convenient helper function that automatically names the steps in your pipeline based on their class names (e.g., 'simpleimputer', 'logisticregression'). You can also construct a Pipeline object manually, which requires you to provide a name for each step. This gives you more control but is slightly more verbose.

The following video provides a great side-by-side comparison.

Using Scikit-Learn Pipelines for Data Preprocessing with Python

In this clip, Nicholas Renotte explains the practical difference between using make_pipeline and instantiating Pipeline directly.

Watch the section from "difference between pipeline and make pipeline". Notice how make_pipeline is shorter to write, while the manual Pipeline approach lets you define custom names for each step (e.g., 'scaling', 'rf_model').

For most cases, make_pipeline is sufficient, but knowing how to construct a Pipeline manually is useful for complex scenarios or when you need more descriptive step names.

Handling Mixed Data with ColumnTransformer

Real-world datasets are rarely so simple. You'll almost always have a mix of numerical and categorical features that require different treatments. This is where ColumnTransformer becomes essential.

The workflow is as follows:

  1. Identify which of your columns are numerical and which are categorical.
  2. Create a Pipeline for your numerical columns (e.g., SimpleImputer with strategy='mean', followed by StandardScaler).
  3. Create a separate Pipeline for your categorical columns (e.g., SimpleImputer with strategy='most_frequent', followed by OneHotEncoder).
  4. Use ColumnTransformer to apply the numeric pipeline to the numeric columns and the categorical pipeline to the categorical columns.
  5. Finally, create one last Pipeline that contains your ColumnTransformer as the first step and your machine learning model as the second step.

This sounds complex, but it's a very logical and powerful pattern. The following resource provides an exceptionally clear code walkthrough of this entire process.

Regression Pipelines in Scikit-learn

This article provides a superb, step-by-step guide to building a full preprocessing pipeline for the House Prices dataset, which contains a challenging mix of 79 numerical and categorical features.

Please read through Section 4: Building the Pipeline. Follow the logic carefully: First, see how a categorical_preprocessor is defined. Next, examine the more complex numeric_preprocessor. Then, observe how ColumnTransformer is used to combine these two pipelines. Finally, see how the complete preprocessor is added to a final pipeline with a regression model. The use of TransformedTargetRegressor is also a neat trick for handling skewed target variables.

To see this process in a live-coding context, the video from Nicholas Renotte provides a hands-on demonstration. He discovers how to use ColumnTransformer on the fly, which gives you a realistic view of how a data scientist might approach this task.

Using Scikit-Learn Pipelines for Data Preprocessing with Python

This part of the video is a live demonstration of building a ColumnTransformer to handle the numeric and categorical features of the House Prices dataset.

Watch the segment from "let's make this a little bit tad smaller". Follow along as he: Identifies categorical and numerical feature names. Defines separate, simple pipelines for each type. Constructs the ColumnTransformer to apply these pipelines to the correct columns. Integrates the ColumnTransformer into a final Pipeline with a model.


From Notebook to Reproducible Script

You've now seen how to build a powerful scikit-learn pipeline object. In a professional setting, you wouldn't just leave this in a messy notebook. You would structure it as part of a clean, reproducible project.

Your software engineering background gives you a significant advantage here. The principles of modularity, version control, and automation that you apply to web development are directly applicable to data science. The next resource demonstrates how to structure an end-to-end machine learning project, moving from raw data to a final report in a clean, script-based workflow.

Ch 10: End-to-End Data Pipeline | Python Guide - Chenhao Zhou

This guide from Chenhao Zhou's "Python Guide" is a masterclass in building a professional, end-to-end data science project. It bridges the gap between notebook experimentation and production-ready code.

Please read through the chapter, paying close attention to the following sections: Section 10.1: Study the recommended project structure. Note the separation of data/raw, data/processed, src, and notebooks. Sections 10.2-10.5: Skim through the steps of loading, cleaning, EDA, and feature engineering. This should all be familiar territory. Section 10.7: This is the core. See how a scikit-learn Pipeline is used to implement the predictive modeling step within this larger script. Sections 10.9-10.13: Read these sections carefully. They cover best practices that are crucial for creating robust pipelines: packaging code into functions, using logging, handling command-line arguments, managing dependencies, and unit testing. These practices are the hallmark of a professional data scientist.

The key takeaway is that the scikit-learn Pipeline object is a component within a larger, well-engineered project. By adopting this structure, you ensure your work is not only correct but also reproducible, maintainable, and easy for collaborators (or your future self) to understand.

Finally, once your entire pipeline is trained, you'll want to save it for future use. The joblib library is preferred for saving scikit-learn objects.

Building a Machine Learning Pipeline with Python and Scikit-Learn | Step-by-Step Tutorial

This final clip from the Ryan & Matt Data Science video shows how to save and load a trained pipeline.

Watch the short section on saving the pipeline. This simple joblib.dump() and joblib.load() pattern is all you need to persist your work.


Conclusion

In this lesson, you've learned how to assemble all your preprocessing and feature engineering skills into a single, cohesive workflow. This is a significant step that moves you from performing isolated tasks to engineering a complete data processing system.

Key Takeaways:

  • Pipelines are Essential: They prevent data leakage, organize your code, and ensure reproducibility, forming the backbone of any serious machine learning project.
  • ColumnTransformer is Key: For real-world datasets with mixed data types, ColumnTransformer is the tool you'll use to apply different preprocessing steps to different columns.
  • Structure Your Project: A scikit-learn pipeline is one part of a larger, well-organized project. Adopting software engineering best practices like modular code, logging, and testing will make your work more robust and professional.
  • Save Your Work: Use joblib to save your fitted pipeline object, allowing you to easily reload it for making predictions on new data or for deployment.

What's Next:

You are now fully equipped with the tools to tackle the final stage of our project. You have a strategy for selecting models and an engineering pattern for preparing your data. In the next lessons, you will combine these skills. You will take this preprocessing pipeline, feed its output into multiple candidate models, evaluate and compare their performance, and ultimately select and justify a final model.