LensKit (LKPY)
repository·main·Indexed 43 days ago
https://github.com/lenskit/lkpyA set of Python tools for experimenting with, training, running, and evaluating recommender systems, optimized for research and education. Version 2026.3.0 includes core abstractions for data management, pipelines, and diagnostics, along with built-in models such as ALS, Funk SVD, and K-Nearest Neighbors. It provides a comprehensive evaluation suite with metrics and tuning utilities, as well as a CLI for data conversion and pipeline execution.
What's inside LensKit
- LensKit is a set of Python tools designed for experimenting with and studying recommender systems. It is built to be modular, flexible, and tested, providing support for training, running, and evaluating recommender algorithms in ways suitable for both research and education.
Note on the deprecated Java version of LensKit
mainThe Java version of LensKit is deprecated. This repository (lkpy) provides the Python implementation. If you require the Java version, you can find its documentation at https://java.lenskit.org.Overview of LensKit Core Abstractions
mainLensKit is organized into several core modules that handle the fundamental aspects of recommendation systems. These modules include:
lenskit: The main entry point.lenskit.data: Tools for managing and loading recommendation data.lenskit.pipeline: Framework for defining and executing recommendation workflows.lenskit.diagnostics: Tools for analyzing model performance and behavior.lenskit.operations: Core operations used within the library.lenskit.training: Logic for training recommendation models.lenskit.config: Configuration management for LensKit components.
Understand the ml-latest-small dataset structure
mainThe
ml-latest-smalldataset is a development dataset containing 100,004 ratings and 1,296 tags across 9,125 movies from 671 users. It is provided as a set of CSV files. Note that this is a development dataset and may change over time; it is not recommended for shared research results. For research, use official benchmark datasets instead.Key Data Properties:
- Encoding: UTF-8.
- Format: Comma-separated values (CSV) with a single header row. Columns containing commas are escaped with double-quotes (
"). - User IDs: Anonymized and consistent across
ratings.csvandtags.csv. - Movie IDs: Consistent across
ratings.csv,tags.csv,movies.csv, andlinks.csv.
Use FlexMFImplicitScorer presets and advanced configuration
mainThe
FlexMFImplicitScorersupports multiple loss functions and sampling strategies. You can usepresetto quickly configure the model to match published research models, or manually override specific settings.Presets
Set the
presetoption in the configuration to one of the following:"bpr": Configures Bayesian Personalized Ranking (pairwise loss, uniform sampling)."warp": Configures Weighted Approximate Rank Loss (warp loss, misranked sampling)."lightgcn": Configures LightGCN (pairwise loss, uniform sampling, 3 convolution layers).
Loss Functions (
loss)"logistic": Logistic loss (standard for Logistic Matrix Factorization)."pairwise": Pairwise rank loss (used in BPR)."warp": Weighted approximate rank loss (requiresnegative_strategy="misranked").
Sampling Strategies (
negative_strategy)"uniform": Samples negative items uniformly at random (default for logistic and pairwise)."popular": Samples negative items proportional to their popularity."misranked": Samples negative items based on current model scores to find misranked items (required for WARP loss).
LightGCN Mode
To enable neighborhood aggregation (LightGCN style), set
convolution_layersto a positive integer. This adds layers of aggregated neighbor embeddings to the model.Entity Representation and Identifiers
mainEntities are defined by their class and identifier.
- Standard Classes: Every dataset includes the
itemclass. Most includeuser. Session-aware datasets may includesession. - Tabular Mapping:
- Identifiers are stored in columns named
<class>_id(e.g.,user_id,item_id). - LensKit uses
<class>_numto represent the 0-based contiguous array index (the entity number) used for mapping identifiers to array indexes.
- Identifiers are stored in columns named
- Standard Classes: Every dataset includes the
How LensKit handles parallel processing
mainLensKit utilizes several different mechanisms for parallel execution depending on the task:
- Batch operations: Uses either a thread pool (on free-threaded Python 3.14+) or Ray (if
lenskit[ray]is installed). - Model training: Most LensKit models use Rayon via the Rust extension module.
- Inference: Uses Rayon via the Rust extension module.
- Backend computation: Uses parallel computation in backends like BLAS, MKL, or Torch for both training and inference.
Note for Python 3.14+ users: You can achieve optimal multithreaded performance by using a free-threaded build of Python. You can install such a version using
uv:uv venv -p 3.14tIf you are on a non-free-threaded Python version and want to parallelize batch inference, you must install Ray (
pip install lenskit[ray]).- Batch operations: Uses either a thread pool (on free-threaded Python 3.14+) or Ray (if
Use BatchPipelineRunner for general batch runs
mainTherecommendandpredictfunctions are convenience wrappers around theBatchPipelineRunnerclass. For more complex or customized batch execution logic, you can useBatchPipelineRunnerdirectly.How pipeline components are defined and configured
mainPipeline components are callable objects. They can be simple Python functions or classes extending the
Componentbase class.Component Inputs
Inputs are defined by the keyword arguments in the component's
__call__method (for classes) or the function signature (for functions). Note: Input names cannot begin with_as these are reserved for internal LensKit use.Configuration
LensKit components separate logic from configuration. Configuration is stored in a separate object (a Python
dataclassor a PydanticBaseModel) and is validated via Pydantic.To implement a configurable component:
- Extend the
Componentclass. - Declare an instance variable whose type is the configuration object type.
Component.__init__will handle storing the configuration or instantiating it from keyword arguments.
Adding Components to a Builder
There are two ways to add components to a
PipelineBuilder:- Pre-instantiated:
builder.add_component('name', MyComponent(option='value')) - Class and Config separately:
builder.add_component('name', MyComponent, MyConfig(option='value'))builder.add_component('name', MyComponent, {'option': 'value'})(The builder will instantiate the component during.build()).
- Extend the
Understand the ItemList abstraction
mainAn
ItemListis a core LensKit abstraction used to represent a list of items along with associated metadata like scores, ratings, or other fields.Key characteristics:
- Versatile IDs: Supports both item IDs (e.g., strings) and numbers.
- Backend-agnostic: Fields (except the item ID) can be presented as NumPy arrays, Pandas series (optionally indexed by ID or number), or Torch tensors.
- Use cases: Represents user history, candidate items for scoring, recommendation results, or test data.
from lenskit.data import ItemList il = ItemList(item_ids=['a', 'b'], scores=[1.5, 1.2], rating=[3, 5])Understand the MovieLens data model in LensKit
mainWhen loading MovieLens data, LensKit organizes the information into standard entities and attributes:
Entities and Interactions
- Users: The user entity.
- Items: The movie entity.
- Ratings: The interaction class representing user-provided ratings.
Item Attributes
title: The movie title.genres: A list of genres for the movie.tag_counts: A sparse vector attribute summarizing thetagsdata (number of times each tag was applied). Tag names are accessible via the attribute's.namesproperty.tag_genome: A vector attribute storing relevance values from the tag genome (available for ML20M and ML25M datasets).
User Attributes
Most datasets do not include user attributes, but ML100K and ML1M include:
genderagezip_code
Rating Attributes
Each rating interaction contains:
rating: The numerical score.timestamp: The time of the rating, parsed into Arrow/NumPy/Pandas timestamp formats.
Split data for offline evaluation with lenskit.splitting
mainThe
lenskit.splittingmodule provides functions to splitlenskit.data.Datasetobjects into train-test splits for offline evaluation. These functions return one or moreTTSplitobjects, which containtrain_dfandtest_dfattributes.Note on Version Changes: As of version 2025.1, data splitting has moved from
lenskit.crossfoldtolenskit.splitting, and function interfaces have been revised.import pandas as pd from lenskit.data import load_movielens from lenskit.splitting import crossfold_users, SampleN dataset = load_movielens('data/ml-20m.zip') # Perform a user-based 5-fold cross-validation for i, tp in enumerate(crossfold_users(dataset, 5, SampleN(5))): tp.train_df.to_parquet(f'train-{i}.parquet') tp.test_df.to_parquet(f'test-{i}.parquet')