sklearn2pmml exports a fitted Scikit-Learn pipeline as PMML through Java
Python library for converting Scikit-Learn pipelines to PMML
At a glance
- What is it?
- sklearn2pmml is a Python wrapper around the JPMML-SkLearn converter that turns a fitted Scikit-Learn pipeline into a PMML document, with a PMMLPipeline class that captures the metadata native estimators lack. It suits teams shipping models to a Java or non-Python runtime, and it is not a way to avoid a Python dependency.
- Who is it for?
- Adopt sklearn2pmml when your target runtime reads PMML and you need a fitted Scikit-Learn pipeline exported with the metadata that native estimators do not carry, and skip it when the deployment target can run Python, since the converter needs a Java runtime on the path.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 54 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A Java converter sits underneath, and Java is a hard prerequisite
The single most important fact about sklearn2pmml is stated in the features section: this package is a thin Python wrapper around the JPMML-SkLearn library. That library is a Java project, and the prerequisites section states that Java 11 or newer is required and that the Java executable must be available on the system path. Python 3.8 or newer is the other requirement. So the toolchain for exporting a model from Python includes a JVM, which surprises people who assume a pure Python conversion path. The consequence for deployment is the interesting part. The conversion happens on the machine that trains the model, and the artefact that comes out is a PMML document, which is XML describing the model, its inputs and its transformations. A runtime that only reads PMML never needs Python, scikit-learn, or a JVM, even though the export step needed all three. That asymmetry is the whole value proposition of the tool and also the reason to think carefully about where the export runs.
Conversion of a live estimator is one function call
The library API is small at the top level. The sklearn2pmml.sklearn2pmml() utility function takes a fitted estimator and an output path:
from sklearn2pmml import sklearn2pmml
estimator = ...
estimator.fit(X, y)
# Convert a live estimator object
sklearn2pmml(estimator, "Estimator.pmml")The estimator argument may also be a path-like object pointing at an estimator pickle file in the local filesystem, and the same function handles that case:
from sklearn2pmml import sklearn2pmml
import joblib
joblib.dump(estimator, "Estimator.pkl")
sklearn2pmml("Estimator.pkl", "Estimator.pmml")That second form is the one that matters for a pipeline of automation, since the pickle can be produced by a training job and converted later by a separate step. The supported surface is wide: the documentation says a wide variety of Scikit-Learn and Scikit-Learn adjacent estimators can be converted as-is, and the authoritative list of supported transformer, selector and predictor classes lives in the features.md file of the JPMML-SkLearn project rather than in this repository. The version coupling matters too. One and the same package version is able to work with all Scikit-Learn 0.17 and newer versions, so the recommendation is to keep the converter on the latest release.
Unpickling happens in a custom Java component, not the Python one
There is a security-relevant detail that is easy to miss and worth stating plainly. SkLearn2PMML uses a custom Java component, rather than the built-in Python unpickler component, for reading pickle files, and the documentation says as such it is safe to use with unvetted pickle files. This matters because loading a pickle from an untrusted source is normally a remote code execution risk, since the standard unpickler can instantiate arbitrary objects. By reading the pickle inside the Java side of the converter, the Python interpreter never executes the pickler's reduce directives. The command line application accepts those files too, and the input option supports joblib, pickle or dill variants. Whether that guarantee covers every pickle payload the Java component will accept is not something the documentation goes into, so the sane reading is that this reduces a class of risk rather than eliminating it, and that a pickle from an unknown source still deserves suspicion.
The module is executable and takes an input and an output path
There is a command line application as well as the library. The sklearn2pmml module is executable, and the main application simply calls the same utility function, so the two paths cannot drift apart. At minimum you give it an input pickle file with the input option and an output PMML file path with the output option:
python -m sklearn2pmml --input Estimator.pkl --output Estimator.pmmlAll supported options are listed by passing the help flag:
python -m sklearn2pmml --helpOn some platforms the Pip installer additionally exposes the main application as a top-level command, which is the shorthand form:
sklearn2pmml --input pipeline.pkl --output pipeline.pmmlThe packaging metadata confirms this. The setup script registers a console_scripts entry point mapping sklearn2pmml to sklearn2pmml.cli:main, and it also ships a resources package containing classpath.txt and jar files, which is how the Java converter is located at runtime. The project also exposes a Python package directory, a src directory, a pom.xml, a NOTICE.txt and a LICENSE.txt, so the repository carries both the Python and the Java sides.
PMMLPipeline exists because native estimators carry too little metadata
The reason the PMML-enhanced variant exists is stated as a limitation of Scikit-Learn itself. Native Scikit-Learn estimators have rather limited portability between environments, because they lack adequate metadata, and the example given is that they did not collect and store even the most important metadata about the feature matrix, the feature_names_in_ attribute, prior to Scikit-Learn 1.0 around 2021. The PMMLPipeline class extends sklearn.pipeline.Pipeline and fixes that by collecting feature and label metadata during the fit(X, y) call. The column names of the X dataset become input field names, and otherwise they default to x1, x2 and so on up to the feature count. The column names of the y dataset become target field names, defaulting to y in the single output case and to y1, y2 and so on in the multi-output case. On top of that it adds prediction post-processing through predict_transform, predict_proba_transform and apply_transform, a verify(X) method that embeds model verification data, a configure method that takes pmml options and controls the representation of the final estimator step, and a customize(command, xpath_expr, pmml_element) method that edits PMML XML fragments by insert, update or delete. Beyond the pipeline, the package provides PMML-oriented transformer, selector and predictor classes organised into four modules. The decoration module captures or declares the operational type of individual features with ContinuousDomain, CategoricalDomain and OrdinalDomain, and gives transformed features meaningful names with Alias and MultiAlias. The preprocessing module handles feature transformation, with ExpressionTransformer for any to any conversion and CutTransformer for continuous to discrete, plus LookupTransformer for discrete to discrete and others. The cross_reference module cross-references features and transformed features at later transformer steps using Memorizer and Recaller. The ensemble module estimates conditionally with SelectFirstTransformer and combines predictors through GBDTLRClassifier and GBDTLMRegressor. The postprocessing module transforms predictions with BusinessDecisionTransformer. The point of these meta-transformers is that PMML is a richer specification than what a scikit-learn pipeline natively expresses, and each one maps a scikit-learn concept onto a PMML construct so the exported document is not just a prediction function but a fuller description of the model's input domain and business rules.
A representative sample is embedded so the deployed model can self-check
The enhanced workflow is worth reading as a whole, because the verify step is the part that is easy to skip and the part that earns its keep later:
#from sklearn.pipeline import Pipeline
from sklearn2pmml import sklearn2pmml
from sklearn2pmml.pipeline import PMMLPipeline
#pipeline = Pipeline(...)
# Activate prediction post-processing
pipeline = PMMLPipeline(..., predict_transformer = ...)
pipeline.fit(X, y)
# Embed small but representative sample for self-check purposes during deployment
pipeline.verify(X.sample(n = 10))
# Default prediction
yt = pipeline.predict(X)
# Default prediction, together with its transformation results
yt_transformed = pipeline.predict_transform(X)
# Default PMML representation
sklearn2pmml(pipeline, "Pipeline.pmml")The comment describes the intent exactly: embed a small but representative sample for self-check purposes during deployment. The PMML document then carries ten rows of expected behaviour, so a runtime can compare its own predictions against the reference and report a mismatch instead of silently returning different numbers. For a model that gets shipped and then re-scored months later, with a data pipeline that may have changed underneath, that verification payload is what turns a silent regression into a visible failure.
AGPL-3.0, no tagged releases, and a dependency matrix that tracks Python versions
The licence is AGPL-3.0, which is the detail most likely to matter in a procurement conversation, because the copyleft reach of the AGPL covers networked use as well as distribution. Anyone shipping a service that exposes the converted model over a network needs to read the licence terms for their specific situation rather than assume the tool is inert, because the conversion output is a data artefact rather than a copy of the library, and how that artefact is treated is a question the licence text answers, not this article. The repository has no GitHub releases, so versioning comes from the package itself: the current version is 0.133.1 dated 30 August 2026, installed with pip install sklearn2pmml==0.133.1, and the last push was on 2026-08-30. The requirements file shows a large and carefully pinned dependency matrix, with separate pins of numpy, pandas, polars, pcre2, statsmodels and TPOT per Python version from 3.8 upwards, plus lightgbm, xgboost, optbinning, scikit-lego, scikit-tree, CHAID and scipy for the estimators being converted. The setup script declares scikit-learn>=1.0 as an install requirement and the requirements file caps it at 1.9.0.
Where sklearn2pmml is the wrong tool
Three cases argue against it. The first is a deployment that can happily run Python, because a PMML document buys you nothing when the target already has scikit-learn, and you take on a Java dependency in the training pipeline for no benefit. The second is an estimator outside the supported list, and the authoritative list lives in another repository's features.md file, so the check has to happen before you design the workflow, not after. The third is a team that treats pickle files as trusted artefacts, because while the custom Java component makes the conversion step safe to run with unvetted pickles, the training job that produced the pickle still ran the training code, and the pipeline in the pickle still has to be understood. There is a further structural limit. The exported PMML is a snapshot of a fitted pipeline, so any retraining means a re-export, and a consumer of that PMML has to be able to execute what was exported, which for a transformer-heavy pipeline is a real compatibility surface outside Python. The documentation does not describe a rollback procedure for a PMML version, so an application that swaps documents at runtime should keep the previous file until the new one has passed its verification check.
Editorial conclusion
Adopt sklearn2pmml when your target runtime reads PMML and you need a fitted Scikit-Learn pipeline exported with the metadata that native estimators do not carry, and skip it when the deployment target can run Python, since the converter needs a Java runtime on the path. Verify first that Java 11 or newer is on the system path, that your specific estimator classes appear in the supported list of the JPMML-SkLearn project, and that the AGPL-3.0 licence is acceptable for how you intend to distribute the result.
Frequently asked questions
How do I convert a Scikit-Learn pipeline to PMML?
Call the sklearn2pmml.sklearn2pmml() utility function with a fitted estimator and an output path, for example sklearn2pmml(estimator, "Estimator.pmml"). The estimator argument may also be a path-like object pointing at a joblib, pickle or dill file on the local filesystem.
What does sklearn2pmml need installed besides Python?
Java 11 or newer, with the Java executable available on the system path, because the package is a thin Python wrapper around the JPMML-SkLearn library. Python 3.8 or newer is the other stated prerequisite.
Is it safe to convert an unvetted pickle file?
The documentation states that SkLearn2PMML uses a custom Java component rather than the built-in Python unpickler component for reading pickle files, and as such it is safe to use with unvetted pickle files.
What is PMMLPipeline for?
It extends sklearn.pipeline.Pipeline to collect feature and label metadata during fit(X, y), since native estimators lack adequate metadata, and adds prediction post-processing, a verify(X) method that embeds model verification data, a configure method and a customize method for editing PMML XML fragments.
What licence is sklearn2pmml under and what version is current?
The project is licensed under AGPL-3.0, and the LICENSE.txt file in the repository carries the terms. The current version is 0.133.1 dated 30 August 2026, and the repository has no GitHub releases, so the package version is the version of record.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jpmml-sklearn2pmml)Was this useful?