Sklearn custom transformers difference between using FunctionTransformer and subclassing TransformerMixin
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
In Scikit-learn, FunctionTransformer and a custom class based on TransformerMixin solve similar problems at different levels of complexity. FunctionTransformer is ideal for small stateless transformations, while subclassing BaseEstimator and TransformerMixin is the better choice when the transformer needs learned state, custom parameters, validation logic, or richer integration with pipelines and model selection.
Use FunctionTransformer for Simple Stateless Logic
If the transformation is just “apply this function to X” and there is nothing to learn during fit, FunctionTransformer is usually enough:
This is concise and pipeline-friendly. It works well for transformations such as:
- log scaling
- clipping
- columnwise arithmetic
- simple deterministic reshaping
The main limitation is that there is no learned internal state unless you build that logic elsewhere.
Subclass When the Transformer Needs fit
If the transformer must learn something from the training data, a custom class is the right tool. For example, a transformer that stores column medians during fit and uses them during transform:
This is not a good fit for FunctionTransformer, because the behavior depends on learned statistics from the dataset.
Why BaseEstimator and TransformerMixin Matter
The typical Scikit-learn custom transformer inherits from both BaseEstimator and TransformerMixin:
- '
BaseEstimatorgives you parameter handling that works withget_params,set_params, cloning, and grid search' - '
TransformerMixingives you a defaultfit_transform'
That makes the custom transformer behave like a normal Scikit-learn component inside Pipeline, ColumnTransformer, and parameter search tools.
Parameterization Is Easier with a Class
Once the transformer has meaningful configuration, a class becomes easier to manage. For example:
This integrates naturally with grid search because the parameters are explicit and discoverable by Scikit-learn.
Feature Names and Validation
Custom classes also make it easier to add input validation, preserve metadata, or expose feature-name behavior. If your transformer interacts with DataFrames, selected columns, or feature engineering that changes column count, a dedicated class often becomes much easier to maintain than a wrapped free function.
That is especially true once the transformer is more than one or two lines long. FunctionTransformer stays elegant for tiny logic; beyond that, it can become opaque.
Common Pitfalls
The most common mistake is using FunctionTransformer for a transformation that really needs learned state from fit. That often leads to awkward global variables or duplicated logic.
Another pitfall is writing a custom transformer class but forgetting BaseEstimator, which makes parameter inspection and cloning less reliable inside Scikit-learn utilities.
It is also easy to underestimate how quickly a “simple function” grows into real transformer logic with parameters, validation, and metadata concerns. At that point, forcing it to stay a plain function usually hurts readability.
Finally, do not choose the class approach only because it looks more official. If the transformation is a small stateless function, FunctionTransformer is often the cleanest answer.
Summary
- Use
FunctionTransformerfor small stateless transformations. - Subclass
BaseEstimatorandTransformerMixinwhen the transformer needs learned state or richer behavior. - Custom classes integrate more naturally with parameter search and complex pipeline logic.
- '
FunctionTransformeris concise, but it becomes awkward once the logic grows.' - The right choice depends less on style and more on whether
fitactually needs to learn something.
Related reading
- sklearn doesn't have attribute 'datasets
- sklearn dumping model using joblib, dumps multiple files. Which one is the correct model?
- sklearn error ValueError Input contains NaN, infinity or a value too large for dtype''float64''
- Sklearn fit vs predict, order of columns matters?
- sklearn GridSearchCV not using sample_weight in score function
- SKLearn how to get decision probabilities for LinearSVC classifier
- sklearn How to reset a Regressor or classifier object in sknn
- sklearn ImportError cannot import name plot_roc_curve
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.