# NTO AI 2025-2026: Baseline for the team stage

*English translation by SOTA – AI Community of the Russian original. Organisers who would like this translation removed can email sota.ai.community@gmail.com.*

> **Disclaimer:** This baseline is only a starting point for your own solution. Participants can and should modify it as they see fit. We strongly recommend experimenting: trying different models and validation approaches, creating new features and building ensembles. This code is not a mandatory part of your final solution; it only helps you get started faster.

Baseline solution for the team-stage task of the NTO 2025/2026 competition ("Artificial Intelligence" profile).

## Description

The model predicts the relevance of books from the candidate pool for a user, with a three-level relevance system:
- **Class 2**: Books read (`has_read=1`)
- **Class 1**: Planned books (`has_read=0`)
- **Class 0**: "Cold" candidates (books the user did not interact with)

This is a Learning-to-Rank task in which, for each user, the given list of candidate books must be ranked so that the books read are in the first positions, the planned books below them and the "cold" candidates at the end.

**Model**: the gradient boosting library `LightGBM` is used with multiclass classification (objective="multiclass", num_class=3)

**Validation**: a methodologically correct split by time (`temporal split`) is applied. Training is done on earlier data and validation on later data, which simulates the real task

**Features**:
- Interaction: a binary feature indicating whether the user interacted with the book in the training set
- Aggregated: the mean share of books read (mean(has_read)) and the number of interactions for users, books and authors
- Metadata: gender, age, year of publication, language, publisher
- Text (TF-IDF): features based on bigrams from the book descriptions
- Text (BERT): embeddings from the Russian-language model `DeepPavlov/rubert-base-cased`

**Ranking**: a weighted sum of the class probabilities is used: `ranking_score = p1 * 1 + p2 * 2`, where p1 and p2 are the probabilities of classes 1 and 2 respectively

**Solution format**: for each user, a ranked list of up to 20 books in CSV format: `user_id,book_id_list` (books separated by commas)

**Metric**: NDCG@20 with three-level relevance (2 points for books read, 1 point for planned books, 0 points for "cold" candidates)

## Quick start

### Virtual environment

Before installing the dependencies, it is recommended to create and activate a virtual environment to isolate the project's dependencies.

```bash
# Create the virtual environment
python -m venv .venv

# Activate (Linux/macOS)
source .venv/bin/activate

# Activate (Windows, PowerShell)
.venv\\Scripts\\Activate.ps1
```

### Installing Poetry

Poetry is used to manage the project's dependencies. If you do not have Poetry installed yet, use the official installation method.

**Linux / macOS / WSL (Windows)**

```bash
curl -sSL https://install.python-poetry.org | python3 -
```

After installation, you may need to add Poetry to `PATH`. Follow the instructions in the terminal.

**Windows (PowerShell)**

```powershell
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
```

Once `Poetry` has been installed successfully, you can move on to installing the project's dependencies.

### Installing the dependencies

```bash
poetry install
```

### Data structure

Make sure that the directory `data/raw/` contains the following files:

```
data/raw/
├── train.csv          # Interaction history (has_read=0 and has_read=1)
├── targets.csv        # List of users to rank for
├── candidates.csv     # Candidate pools for each user
├── books.csv          # Book metadata
├── users.csv          # User metadata
├── genres.csv         # Reference table of genres
├── book_genres.csv    # Link between books and genres
└── book_descriptions.csv  # Book descriptions
```

### Running the pipeline

The pipeline is split into separate stages for efficiency and so that processed data can be reused:

```bash
# 1. Data preparation (loading, filtering, feature engineering)
poetry run python -m src.baseline.prepare_data

# 2. Model training (uses the prepared data)
poetry run python -m src.baseline.train

# 3. Prediction (uses the prepared data and the trained models)
poetry run python -m src.baseline.predict

# 4. Submission validation
poetry run python -m src.baseline.validate
```

Or via the Makefile:

```bash
make download-data # Download and unpack the data
make prepare-data  # Data preparation
make train         # Training
make predict       # Prediction
make validate      # Validation
make run           # Full cycle (prepare-data + train + predict + validate)
make clean         # Delete all generated files (data, models, submissions)
```

**Note:** Data preparation (`prepare-data`) must be run before training and prediction. The prepared data are saved in `data/processed/` and reused without recomputing the features.

## Project structure

```
.
├── data/
│   ├── raw/              # Source data
│   ├── interim/          # Intermediate data (if needed)
│   └── processed/        # Processed data with features
├── docs/                 # Documentation
│   ├── data.md           # Data description
│   └── task.md           # Task description
├── output/
│   ├── models/           # Trained models
│   └── submissions/      # Submission files
├── src/baseline/
│   ├── config.py         # Configuration and model parameters
│   ├── constants.py      # Project constants (file and column names)
│   ├── data_processing.py # Loading and merging the raw data
│   ├── features.py       # Feature engineering
│   ├── prepare_data.py   # Data preparation (loading, processing, saving)
│   ├── temporal_split.py # Utilities for a correct temporal split of the data
│   ├── train.py          # Model training (uses the prepared data)
│   ├── predict.py        # Generating predictions (uses the prepared data)
│   ├── validate.py       # Checking the submission format
│   └── evaluate.py       # Evaluating prediction quality (metrics)
└── Makefile              # Convenient commands
```

## Dependencies

- Python >= 3.10
- pandas, scikit-learn, lightgbm, joblib
- transformers, torch, sentencepiece
- ruff, pre-commit (dev)
