Metadata-Version: 2.4
Name: warm-transfer
Version: 0.1.0
Summary: Model-agnostic plug & play library for transferring and calibrating a trained recommender's scores onto cold-start items, plus a reproducible benchmark
Project-URL: Repository, https://github.com/pacifikus/warm-transfer
Project-URL: Documentation, https://pacifikus.github.io/warm-transfer/
Project-URL: Issues, https://github.com/pacifikus/warm-transfer/issues
Author-email: Nikita Tenishev <nik.tenishev@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: benchmark,cold-start,item-cold-start,recommender-systems,recsys
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Requires-Dist: numpy>=1.26
Requires-Dist: pandas>=2.1
Requires-Dist: pydantic>=2.6
Requires-Dist: scikit-learn>=1.4
Requires-Dist: scipy>=1.11
Provides-Extra: all
Requires-Dist: catboost>=1.2; extra == 'all'
Requires-Dist: implicit>=0.7; extra == 'all'
Requires-Dist: psutil>=5.9; extra == 'all'
Requires-Dist: pyarrow>=15; extra == 'all'
Requires-Dist: pyyaml>=6.0; extra == 'all'
Requires-Dist: rectools>=0.13; extra == 'all'
Requires-Dist: requests>=2.31; extra == 'all'
Requires-Dist: tabulate>=0.9; extra == 'all'
Requires-Dist: torch>=2.2; extra == 'all'
Requires-Dist: tqdm>=4.66; extra == 'all'
Provides-Extra: bench
Requires-Dist: catboost>=1.2; extra == 'bench'
Requires-Dist: implicit>=0.7; extra == 'bench'
Requires-Dist: psutil>=5.9; extra == 'bench'
Requires-Dist: pyarrow>=15; extra == 'bench'
Requires-Dist: pyyaml>=6.0; extra == 'bench'
Requires-Dist: rectools>=0.13; extra == 'bench'
Requires-Dist: requests>=2.31; extra == 'bench'
Requires-Dist: tabulate>=0.9; extra == 'bench'
Requires-Dist: tqdm>=4.66; extra == 'bench'
Provides-Extra: deep
Requires-Dist: torch>=2.2; extra == 'deep'
Description-Content-Type: text/markdown

**English** | [Русский](README.ru.md)

# warm-transfer

**Model-agnostic plug&play library** for transferring and calibrating the scores of an
already-trained recommendation model onto **new (cold-start) items** under extreme
sparsity, plus a reproducible **benchmark**.

Idea: you have a trained model of arbitrary architecture — the library "wraps" on top
of its scores and ranks new products/content for which there are still no (or almost no)
interactions. You don't need to retrain the model, and you don't need access to its
internals either.

## Structure

- **`warmtransfer`** — lightweight core (plug&play). Works with donor scores + content.
  Installs without heavy recsys dependencies.
  - `methods/` — cold-start methods (baselines, KNN, LinMap, Stacking, scale&shift, attention-KNN…)
  - `metrics/` — our own correct metrics (Recall/Precision/MAP/NDCG@k, MRR, AUC, RelaImpr)
  - `similarity/` — content similarity cold→warm (optional)
- **`warmtransfer.bench`** — benchmark (heavy dependencies, extra `bench`).
  - `datasets/` — loaders (ML-1M/20M, Goodbooks, KION/KION-text, Amazon Toys/-text, MIND/-text)
  - `splitters/` — honest pseudo-cold split (anti-leakage)
  - `adapters/` — donor models (ALS, BPR, CatBoost, EASE, Two-Tower)
  - `runner.py` — running the matrix of datasets × donors × methods × baselines

## Key result

The model-agnostic methods **LinMap** (Ridge: content → donor score vector) and **stacking_plus**
(hybrid: linmap signal + personalized popularity) **beat the strong personalized
Grouped MP** across a matrix of **8 dataset loaders × 5 donors** (seed=42): score transfer beats
the baseline on per-user AUC in **36 of 40** dataset×donor cells (90%). The 4 misses are mostly on
ML-1M, where the baseline AUC (~0.72) is already strong. The five donors span four model families
(matrix factorization als/bpr, GBDT catboost, linear item-item ease, neural two_tower) — they are a
**diversity axis** for observing how transfer holds across donor types, not competitors to rank.
Naive methods (knn/attention/debiased/embedding_avg) lose to the baseline — they pull in neighbor
popularity. **Caveat:** these numbers are a single seed; targeted multi-seed runs on the marginal
cells are still pending. Details and tables — `docs/results/full_matrix.md`.

## Plug&play usage (core, without the benchmark)

```python
import numpy as np
import pandas as pd

from warmtransfer.columns import Columns as C
from warmtransfer.methods import LinMap
from warmtransfer.types import ItemFeatures, TransferInputs

warm_features = ItemFeatures(
    item_ids=np.array([10, 11]),
    matrix=np.array([[1.0, 0.0], [0.0, 1.0]]),
    feature_names=["genre_action", "genre_drama"],
)
cold_features = ItemFeatures(
    item_ids=np.array([20]),
    matrix=np.array([[1.0, 0.0]]),
    feature_names=["genre_action", "genre_drama"],
)
donor_scores = pd.DataFrame(
    {
        C.User: [1, 1, 2, 2],
        C.Item: [10, 11, 10, 11],
        C.Score: [5.0, 1.0, 1.0, 5.0],
    }
)

# bring your own warm donor scores + content of warm/cold items
inputs = TransferInputs(
    donor_scores=donor_scores,
    warm_features=warm_features,
    cold_features=cold_features,
)
reco = LinMap(alpha=1.0).fit(inputs, seed=42).predict(
    user_ids=np.array([1, 2]),
    cold_item_ids=np.array([20]),
)
```

Full runnable example: `examples/quickstart.py`.

## Installation

```bash
uv sync                 # core + dev only
uv sync --extra bench   # + donor engines and benchmark infrastructure
uv sync --extra all     # + deep (torch)
```

## Running

```bash
uv run pytest -q                          # core tests
uv run python examples/quickstart.py      # minimal plug&play example
uv run warmbench --list-components        # available datasets/donors/methods
uv run warmbench --config configs/example.yaml --dry-run
uv run warmbench --config configs/example.yaml  # example benchmark run
```

## Documentation

The documentation site is built with MkDocs Material (like RecTools) and published to
GitHub Pages automatically (`.github/workflows/docs.yml`) after a push to the GitHub repository.
Locally:

```bash
uv sync --group docs
uv run mkdocs serve     # local preview at http://127.0.0.1:8000
uv run mkdocs build     # static site in site/
```

Page sources:
- `docs/methods.md` — description of the methods
- `docs/datasets.md` — description of the datasets
- `docs/eval-protocol.md` — split and metrics protocol (anti-leakage)
- `docs/results/` — result tables (full matrix, spread across seeds, ablations)
- `docs/api.md` — auto-generated API reference
