2026 Releases#
2026 builds on the foundation of 2025 to improve the ergonomics of data access, querying, and metrics, and clean up some APIs that seemed good at the time, while making it even easier to use LensKit for recommendation scenarios besides ID-based personalized recommendation.
There are no new major paradigm shifts, though — pipelines, datasets, and components work as they do in the 2025 series, but with more features, some rough corners polished off the interfaces, and hopefully fewer bugs.
2026.1.0#
Breaking Changes#
The
Trainableprotocol now has a separate methodis_trained()to query if a component has been trained, and responsibility for skipping retraining of already-trained components whenretrainisFalsehas been moved from individual components tolenskit.pipeline.Pipeline.train()(🐞 1042, ⛙ 1044).The pipeline builder will issue a warning if a component implements
train()but notis_trained().Pipeline components and inputs now have restrictions on their names, and cannot have names beginning with
_. See Component Names for details.Pipeline configurations serialized with previous versions cannot be re-loaded in LensKit 2026, due to moves of module paths. Import path canonicalization (🐞 948) reduces the risk of such breakage in future releases. Handwritten configurations will often still work.
Many submodules (such as most modules under
lenskit.pipeline) have been renamed to be private modules. Code importing from their original locations will need to be updated to import from the higher-level module (🐞 947).The
AttributeSetclass has been renamed toEntityAttribute(🐞 946), to better clarify its design and role.LensKit now requires Python 3.12.5 or newer, along with NumPy 2.x, Pandas 2.3 or newer, and SciPy 1.13 or newer (see Dependency Versioning, ⛙ 954). Earlier versions of Python 3.12 have a bug in the standard library that affects LensKit.
We no longer publish 32-bit binary wheels.
Removed
DecomposedMetric, as theMetricinterface is now decomposed. All metrics based on listwise measurements or intermediate results should directly extend fromMetricorListMetric. (⛙ 983)GlobalMetrichas been removed. Code needing to compute global metrics should directly compute over item lists.MeasurementCollectorno longer supports defaults when adding metrics.RunAnalysisis deprecated, and no longer supports explicit defaults or global metrics. UseMeasurementCollectorinstead. Its global metric columns have also changed in some cases.ListGiniandExposureGininow require an item vocabulary or dataset as input.Stopped providing wheels for macOS on Intel. Users who still need to run LensKit on Intel-based Macs should use the Conda packages (available in conda-forge and prefix.dev).
Removed the deprecated
lenskit.training.IterativeTrainingbase class in favor oflenskit.training.UsesTrainer.Component class members have been renamed to no longer use the Scikit-Learn pattern of trailing
_in their names.Removed the
lenskit.stats.argtopnfunction (🐞 833).lenskit.data.ItemList.top_n()now uses a Rust-accelerated top-N implementation (⛙ 1049).lenskit.data.ItemList.to_arrow()no longer accepts mappings for its optionalcolumnsargument, sequences of names are used instead (⛙ 1052).Removed the
noption topredict_pipeline()(🐞 835).Removed the deprecated unrated and all-items candidate selectors, in favor of
TrainingItemsCandidateSelector(🐞 935).Several input types to batch inference are no longer supported, to reduce ambiguity and implicit behavior (🐞 958, ⛙ 1074).
New Features#
Added environment variables to
TrainingOptions, along with theenv_var()method to query them. This allows for open-ended configuration of training processes.Added support for free-threaded Python, including binary distributions for Python 3.14t on Linux and macOS (🐞 916, ⛙ 1022).
Added support for parallel batch inference using thread pools on free-threaded Python (🐞 921, ⛙ 1025).
Added SLIM and fsSLIM to
lenskit.knn(🐞 894, ⛙ 896).
Performance Changes#
Minor Changes#
lenskit.metrics.call_metric()has been renamed tomeasure_list(), and the old name preserved as a deprecated alias.Pipeline type-checking for ArrayLike component inputs no longer works, due to a breaking change in NumPy 2.4. No LensKit components used ArrayLike as an input or output data type.
Pipeline component inputs with default values can now have missing inputs (🐞 1000, ⛙ 1001).
Rust progress updates now use a background thread to simplify logic and keep locks out of the work path (⛙ 1008).
Fixed a bug saving item list collections of emtpy item lists to Parquet files (🐞 1051, ⛙ 1052).