Search code examples
pythonscikit-learnpipelinerandom-forestcross-validation

Why am I getting 'last step of pipeline' error when using make_pipeline in scikit-learn?


So I am trying to use make_pipeline in scikit-learn to clean my data (replace missing values and then clean for outliers, apply an encoding function to the categorical variables and then finally add a Random Forest Regressor through RandomForestRegressor. The input is a DataFrame. Eventually I'd like to put this through GridSearchCV to search over optimal hyperparameters for the regressor.

In order to do this I built some custom classes which inherit the TransformerMixin class as advised here. Here is what I have so far

from sklearn.pipeline import make_pipeline
from sklearn.base import TransformerMixin
import pandas as pd

class Cleaning(TransformerMixin):
    def __init__(self, column_labels):
        self.column_labels = column_labels
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        """Given a dataframe X with predictors, clean it."""
        X_imputed, medians_X = median_imputer(X) # impute all missing numeric data with median
        
        quantiles_X = get_quantiles(X_imputed, self.column_labels)
        X_nooutliers, _ = replace_outliers(X_imputed, self.column_labels, medians_X, quantiles_X)
        return X_nooutliers

class Encoding(TransformerMixin):
    def __init__(self, encoder_list):
        self.encoder_list = encoder_list
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        """Takes in dataframe X and applies encoding transformation to them"""
        return encode_data(self.encoder_list, X)

However, when I run the following line of code I am getting an error:

import category_encoders as ce

pipeline_cleaning = Cleaning(column_labels = train_labels)

OneHot_binary = ce.OneHotEncoder(cols = ['new_store']) 
OneHot = ce.OneHotEncoder(cols= ['transport_availability']) 
Count = ce.CountEncoder(cols = ['county'])
pipeline_encoding = Encoding([OneHot_binary, OneHot, Count])

baseline = RandomForestRegressor(n_estimators=500, random_state=12)
make_pipeline([pipeline_cleaning, pipeline_encoding,baseline])

The error is saying Last step of Pipeline should implement fit or be the string 'passthrough'. I don't understand why?

EDIT: slight typo in the last line, correct. The Third element in the list passed to make_pipeline is the regressor


Solution

  • Change the line:

    make_pipeline([pipeline_cleaning, pipeline_encoding,baseline])
    

    to (without list):

    make_pipeline(pipeline_cleaning, pipeline_encoding,baseline)
    Pipeline(steps=[('cleaning', <__main__.Cleaning object at 0x7f617260c1d0>),
                    ('encoding', <__main__.Encoding object at 0x7f617260c278>),
                    ('randomforestregressor',
                     RandomForestRegressor(n_estimators=500, random_state=12))])
    

    and you're fine to go