I am using ColumnTransformer and FunctionTransformer classes to build a preprocessing pipeline for an ML project.
One of my FunctionTransformer uses a function (let's say preprocess_A) defined in my package. I fitted the pipeline and saved it as a pickle file alongside a trained model. Everything seemed to work fine.
I then decided to change preprocess_A definition for a new experiment, but I also noticed a drop in performance for my trained model. The problem is that the pickle file only keeps a reference to preprocess_A but not its definition. Hence, any change in preprocess_A will impact my previous pipelines.
So, is there a way to save my FunctionTransformer object and expect it to always work the same way, even if I later modify preprocess_A?
Code snippet :
### Imports
import pickle
import pandas as pd
# Custom package pipeline
from my_package.preprocessing import preprocess
pipeline = preprocess.get_pipeline()
# pipeline = ColumnTransformer([('test', FunctionTransformer(preprocess_A), make_column_selector())])
# def preprocess_A(x): return x ** 2
### Fit
df = pd.DataFrame({'col1': [1, 2, 4], 'col2': [3, 6, 9]})
pipeline.fit(df)
### Save
with open('test.pkl', 'wb') as f:
pickle.dump(pipeline, f)
### Transform
pipeline.transform(df)
# array([[ 1, 9], [ 4, 36], [16, 81]], dtype=int64)
- def preprocess_A(x): return x ** 2
+ def preprocess_A(x): return x ** 4
### Imports
import pickle
import pandas as pd
### Load pipeline
with open('test.pkl', 'rb') as f:
pipeline = pickle.load(f)
### Transform
df = pd.DataFrame({'col1': [1, 2, 4], 'col2': [3, 6, 9]})
pipeline.transform(df)
# array([[ 1, 81], [ 16, 1296], [ 256, 6561]], dtype=int64)
Note : it works fine with dill and lambda functions, but some preprocessing function can be complex and not easy to transform in lambdas
Note 2 : even if some functions might be complex, they have no dependency to my own package