Skip to main content

Welcome to a Grasp lesson

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

Lesson 8

Data Preprocessing with scikit-learn

Recommended resources

Welcome to the final lesson of our first module on Python for Data Science. In our last session, we mastered the art of creating publication-quality visualizations with Matplotlib and Seaborn. You learned how to transform raw data into clear, insightful plots, a crucial skill for communicating results. Today, we will address the essential step that precedes both modeling and, often, final visualization: data preprocessing.

This lesson directly tackles the learning outcome of preparing data for machine learning models. Raw datasets are rarely ready for direct use. They often contain missing values, non-numeric data, and features on widely different scales. Most machine learning algorithms cannot handle such data. We will cover the three fundamental preprocessing tasks using the scikit-learn library:

  1. Handling missing values: Deciding whether to discard or intelligently fill in missing data points.
  2. Encoding categorical features: Converting text-based or non-numerical data into a machine-readable format.
  3. Applying feature scaling: Standardizing the range of numerical features to ensure algorithms perform optimally.

Finally, we'll see how to combine these steps into a single, elegant, and robust workflow using scikit-learn's Pipeline and ColumnTransformer. The visualization skills you acquired previously will be invaluable here for inspecting your data before and after these transformations to verify their effects.

1. The Necessity of Preprocessing

Machine learning models are, at their core, mathematical functions. They expect clean, numerical input. Feeding them a raw dataset is like asking a calculator to solve an equation containing words and blank spaces—it simply won't work. Preprocessing is the systematic process of cleaning and transforming data into a suitable format.

Beyond simple compatibility, preprocessing directly impacts model performance. For instance, many algorithms, like those based on gradient descent (e.g., linear regression, neural networks) or distance calculations (e.g., k-Nearest Neighbors, SVMs), are sensitive to the scale of features. A feature ranging from 0 to 1,000,000 will dominate another feature ranging from 0 to 1, causing the model to incorrectly perceive it as more important. Proper scaling prevents this.

The following video provides a practical, code-driven overview of the entire preprocessing workflow we'll be discussing.

Scikit Learn Tutorial | Scikit-Learn Workflow | Data Preprocessing In Machine Learning | Intellipaat

This tutorial from Intellipaat walks through a typical data preprocessing sequence on a real dataset. It provides a good initial sense of the problems we aim to solve.

Watch the following sections to get a feel for the main steps: Introduction: The speaker introduces why data cleaning is a necessary first layer in any ML project. Missing Values: See how to identify and visualize missing data and then apply a simple drop strategy. Following that, watch the demonstration of imputing missing numerical values using a 'mean' strategy. Categorical Encoding: Observe how One-Hot Encoding is used to convert a text column ('sex') into numerical format. Feature Scaling: Finally, watch the explanation and implementation of StandardScaler and MinMaxScaler.

Now that you have a practical overview, let's delve into the theory and best practices for each step using scikit-learn's powerful tools.


2. Handling Missing Values

Real-world data is messy. Values can be missing due to data entry errors, sensor failures, or privacy concerns. scikit-learn provides a dedicated module, sklearn.impute, for handling this.

6.4. Imputation of missing values

This official scikit-learn documentation is the definitive guide to its imputation tools. We'll explore the most common strategies.

First, read the introduction and the distinction between univariate and multivariate imputation. This sets the conceptual stage. Next, study the section on Univariate feature imputation, which focuses on the SimpleImputer. Read from the beginning of the section to understand the mean, median, and most_frequent strategies. The mean is a common default, but the median is more robust to outliers. most_frequent is the go-to for categorical features. Then, explore more advanced techniques in the Multivariate feature imputation and Nearest neighbors imputation sections. Read about the IterativeImputer, which models each feature as a function of others. Also, read about the KNNImputer, which fills missing values using the average of the nearest neighbors. These are powerful alternatives to simple statistical imputation. Finally, read about Marking imputed values. The section on the MissingIndicator explains why it can be beneficial to create a new binary feature that indicates whether a value was originally missing. This can be valuable information for the model.

To summarize the imputation strategies:

  • SimpleImputer: Fills missing values using a simple statistic from the same feature column.
    • strategy='mean': Good for normally distributed numerical data.
    • strategy='median': Best for numerical data with outliers.
    • strategy='most_frequent': For categorical (non-numeric) data.
    • strategy='constant': Fills with a fixed value you provide.
  • KNNImputer: A multivariate approach that imputes a value based on the values of its k nearest neighbors in the feature space. It's often more accurate than SimpleImputer if feature relationships are meaningful.
  • IterativeImputer: The most complex of the three. It treats each feature with missing values as a regression problem, using all other features to predict and fill the missing entries in an iterative process.
  • MissingIndicator: Creates new binary columns to flag which values were imputed. This can be used on its own or added via the add_indicator=True argument in other imputers.

3. Encoding Categorical Features

Machine learning models require numerical input. Categorical features, such as country names or product types, must be converted into a numerical representation.

A visual summary of common encoding techniques for transforming categorical data into numerical form, including Label/Ordinal, One-Hot, Target, and Frequency encoding.

Let's focus on the two most fundamental encoding strategies in scikit-learn: OrdinalEncoder and OneHotEncoder.

7.3. Preprocessing data

We now turn to another section of the main preprocessing documentation, this time focusing on categorical features.

Read the main section on Encoding categorical features. This introduces the core problem and OrdinalEncoder. Pay close attention to the explanation of one-hot encoding and its implementation with OneHotEncoder. Skim the sub-section about the drop parameter, particularly the part on dropping a column to avoid co-linearity. This is an important practical consideration.

Here is a breakdown of the key encoders:

  • OrdinalEncoder: Assigns a unique integer to each category (e.g., 'low' -> 0, 'medium' -> 1, 'high' -> 2). This is only suitable for ordinal features, where the categories have a natural, ranked order. Using it on nominal (unordered) data can mislead the model into assuming a false relationship (e.g., that 'blue' is "greater than" 'red').

  • OneHotEncoder: Creates a new binary (0 or 1) column for each category. For a feature 'Color' with values {'Red', 'Green', 'Blue'}, it would create three columns: Color_Red, Color_Green, Color_Blue. For a given row, only the column corresponding to its category will be 1; the others will be 0.

    • Pros: The standard and safest way to encode nominal data without implying any order.
    • Cons: Can lead to a very high number of features if the original category has many unique values (high cardinality), potentially slowing down training.
    • drop='first': To avoid perfect multicollinearity (where one feature can be perfectly predicted by others), you can drop one of the one-hot encoded columns. The information is not lost; if all other columns are 0, it implies the dropped category.
  • TargetEncoder (Advanced): For high-cardinality features where one-hot encoding is infeasible, TargetEncoder is a powerful option. It encodes each category with the mean of the target variable for that category. For example, in a house price prediction task, the category 'San Francisco' would be encoded with the average house price of all listings in San Francisco. This is a very effective technique but must be used with care to prevent data leakage, as it uses information from the target variable. scikit-learn's implementation uses internal cross-validation within fit_transform to mitigate this.


4. Feature Scaling

The final preprocessing step is to scale numerical features. As mentioned, this is critical for algorithms sensitive to the magnitude of input values.

7.3. Preprocessing data

Let's return to the scikit-learn preprocessing documentation to cover the primary scaling methods.

Read the introduction to the topic: Standardization. This explains why scaling is a common requirement. Next, read about the three main scalers: The section on StandardScaler: StandardScaler explained. This transforms data to have a mean of 0 and a standard deviation of 1. The section on MinMaxScaler: MinMaxScaler explained. This scales data to a fixed range, typically [0, 1]. The section on RobustScaler: Scaling with outliers. This scaler uses the median and interquartile range, making it robust to the influence of outliers.

Choosing the right scaler depends on your data and model:

  • StandardScaler: This is the default choice for most applications. It centers the data around zero and is effective for algorithms that assume a Gaussian distribution of features, such as linear and logistic regression.
  • MinMaxScaler: Useful when you need your feature values to be within a specific bounded interval (e.g., [0, 1] for image pixel intensities). It's sensitive to outliers, as a single very large or small value will determine the scaling range for all other points.
  • RobustScaler: The best choice when your dataset has significant outliers. Outliers can heavily skew the mean and standard deviation used by StandardScaler, but they have little effect on the median and interquartile range used by RobustScaler.

5. Putting It All Together: ColumnTransformer and Pipeline

In any realistic project, you will have a dataset with a mix of numerical and categorical features, some with missing values, all requiring different preprocessing. Applying these steps one by one is tedious and, more importantly, prone to data leakage—fitting a scaler on the entire dataset before splitting into training and testing sets contaminates your training process with information from the test set.

The correct, professional approach is to use scikit-learn's Pipeline and ColumnTransformer.

  • A Pipeline chains together multiple processing steps (e.g., imputer -> scaler -> model).
  • A ColumnTransformer applies different pipelines to different columns of your dataset.
This flowchart illustrates a typical workflow using `ColumnTransformer` within a `Pipeline`. Different data types (numeric, categorical) are routed to different preprocessing steps (scaling, encoding) before being combined and fed to a final estimator.

The following video provides an excellent, detailed walkthrough of how to construct and use a ColumnTransformer.

6.1 Scikit-Learn ColumnTransformer [Applied Machine Learning || Varada Kolhatkar || UBC]

This video from the University of British Columbia's Applied Machine Learning course is a clear and concise tutorial on why and how to use ColumnTransformer.

The Problem: Watch the introduction to understand why a simple Pipeline is insufficient for datasets with mixed feature types. Analyzing the Data: See how to identify different feature types (numeric, categorical, etc.) and decide on the appropriate transformations. Creating the ColumnTransformer: This is the core of the lesson. Observe how a ColumnTransformer is defined to apply StandardScaler to numeric columns and OneHotEncoder to categorical columns, while leaving other columns untouched (passthrough). Examining the Output: Learn how the data is transformed and how to retrieve the new column names after one-hot encoding. Integrating into a Pipeline: Finally, see how the ColumnTransformer is seamlessly placed as the first step in a full Pipeline that includes a model.

This workflow—defining separate pipelines for numeric and categorical features and combining them with a ColumnTransformer, which is then placed inside a final Pipeline with a model—is the gold standard for preprocessing in scikit-learn. It is robust, reproducible, and prevents data leakage.

Here's a conceptual code snippet illustrating the pattern:

from sklearn.pipeline import make_pipeline
from sklearn.compose import make_column_transformer
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.linear_model import LogisticRegression




# Define preprocessing for numeric columns
numeric_pipeline = make_pipeline(
    SimpleImputer(strategy='median'),
    StandardScaler()
)




# Define preprocessing for categorical columns
categorical_pipeline = make_pipeline(
    SimpleImputer(strategy='most_frequent'),
    OneHotEncoder(handle_unknown='ignore')
)




# Create the ColumnTransformer to apply pipelines to correct columns
preprocessor = make_column_transformer(
    (numeric_pipeline, ['age', 'fare']),
    (categorical_pipeline, ['embarked', 'sex'])
)




# Create the full pipeline with the preprocessor and the model
full_pipeline = make_pipeline(
    preprocessor,
    LogisticRegression()
)




# Now you can fit the entire pipeline on your raw training data
# full_pipeline.fit(X_train, y_train)

Conclusion

This lesson concludes our foundational module on Python for Data Science and ML by equipping you with the essential skills to prepare data for machine learning models. You now understand not just the "how" but also the "why" behind the most critical preprocessing steps.

Key Takeaways:

  • Preprocessing is mandatory: Raw data is rarely suitable for ML algorithms.
  • Handle missing values systematically: Use SimpleImputer for basic cases and consider KNNImputer or IterativeImputer for more accuracy. Don't forget MissingIndicator if the "missingness" itself is a signal.
  • Encode categorical features correctly: Use OneHotEncoder for nominal data and OrdinalEncoder for ordered data. Be mindful of feature explosion with high-cardinality variables.
  • Scale numerical features: StandardScaler is a robust default, while RobustScaler is ideal for data with outliers and MinMaxScaler is useful for bounded data.
  • Use ColumnTransformer and Pipeline: This is the canonical scikit-learn pattern for building robust, reusable, and leak-proof preprocessing workflows for mixed-type data.

With this, you have completed the practical Python toolkit module. The upcoming modules will shift focus to the mathematical foundations that power the models themselves. In the next lesson, we will begin our exploration of Linear Algebra, starting with vectors and their geometric interpretation. This will lay the groundwork for understanding everything from linear regression to the inner workings of deep neural networks.