Tutorial: Binning process with sklearn Pipeline

This example shows how to use a binning process as a transformation within a Scikit-learn Pipeline. A pipeline generally comprises the application of one or more transforms and a final estimator.

[1]:
import numpy as np
import pandas as pd

from optbinning import BinningProcess

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline

To get us started, let’s load a well-known dataset from the UCI repository

[2]:
class Data:
    def __init__(self, data, target, feature_names):
        self.data = data
        self.target = target
        self.feature_names = feature_names


def load_boston():
    data_url = "../../../tests/data/boston_housing.csv"
    raw_df = pd.read_csv(data_url, sep=r"\s+", skiprows=22, header=None)
    raw_data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
    target = raw_df.values[1::2, 2]
    feature_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS',
                     'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT']

    return Data(raw_data, target, feature_names)

data = load_boston()

variable_names = data.feature_names
X = data.data
y = data.target
[3]:
categorical_variables = ['CHAS']

Instantiate a BinningProcess object class with variable names and the list of numerical variables to be considered categorical. Create pipeline object by providing two steps: a binning process transformer and a linear regression estimator.

[4]:
binning_process = BinningProcess(variable_names,
                                 categorical_variables=categorical_variables)
[5]:
lr = Pipeline(steps=[('binning_process', binning_process),
                     ('regressor', LinearRegression())])

Split dataset into train and test Fit pipeline with training data.

[6]:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
[7]:
lr.fit(X_train, y_train)
[7]:
Pipeline(steps=[('binning_process',
                 BinningProcess(categorical_variables=['CHAS'],
                                variable_names=['CRIM', 'ZN', 'INDUS', 'CHAS',
                                                'NOX', 'RM', 'AGE', 'DIS',
                                                'RAD', 'TAX', 'PTRATIO', 'B',
                                                'LSTAT'])),
                ('regressor', LinearRegression())])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
[8]:
y_test_predict = lr.predict(X_test)

print("MSE:      {:.3f}".format(mean_squared_error(y_test, y_test_predict)))
print("MAE:      {:.3f}".format(mean_absolute_error(y_test, y_test_predict)))
print("R2 score: {:.3f}".format(r2_score(y_test, y_test_predict)))
MSE:      13.602
MAE:      2.490
R2 score: 0.815

In this case, the performance metrics show that the binning process transformation is effective in improving predictions.

[9]:
lr2 = LinearRegression()
lr2.fit(X_train, y_train)

y_test_predict = lr2.predict(X_test)

print("MSE:      {:.3f}".format(mean_squared_error(y_test, y_test_predict)))
print("MAE:      {:.3f}".format(mean_absolute_error(y_test, y_test_predict)))
print("R2 score: {:.3f}".format(r2_score(y_test, y_test_predict)))
MSE:      24.291
MAE:      3.189
R2 score: 0.669

Binning process statistics

The binning process of the pipeline can be retrieved to show information about the problem and timing statistics.

[10]:
binning_process.information(print_level=1)
optbinning (Version 1.0.0)
Copyright (c) 2019-2026 Guillermo Navas-Palencia, Apache License 2.0

  Statistics
    Number of records                    404
    Number of variables                   13
    Target type                   continuous

    Number of numerical                   12
    Number of categorical                  1
    Number of selected                    13

  Time                                1.6123 sec

The summary method returns basic statistics for each binned variable.

[11]:
binning_process.summary()
[11]:
name dtype status selected n_bins woe quality_score
0 CRIM numerical OPTIMAL True 10 93.949585 0.001846
1 ZN numerical OPTIMAL True 3 62.306865 0.380976
2 INDUS numerical OPTIMAL True 7 75.118213 0.048957
3 CHAS categorical OPTIMAL True 2 52.476876 0.149723
4 NOX numerical OPTIMAL True 7 86.777245 0.076548
5 RM numerical OPTIMAL True 9 104.021845 0.030523
6 AGE numerical OPTIMAL True 9 75.403568 0.002715
7 DIS numerical OPTIMAL True 8 73.097554 0.010709
8 RAD numerical OPTIMAL True 4 62.798802 0.414959
9 TAX numerical OPTIMAL True 6 74.957266 0.198384
10 PTRATIO numerical OPTIMAL True 7 73.905115 0.020726
11 B numerical OPTIMAL True 9 83.013298 0.060997
12 LSTAT numerical OPTIMAL True 12 124.279471 0.001821