Ends in 6 weeks
112 participants
100 submissions

Данные для участников

Датасет содержит рекомендательные ленты Авито. Одна строка в impressions — одна лента кандидатов для пользователя. В ней хранятся признаки кандидатов, эмбеддинг пользователя и история его событий. Целевые метки доступны в train и val.

Материалы

Правильные ответы test не входят в публичный архив. Они используются организаторами для расчёта Public- и Private-метрик.

Даты

ЧастьНачалоКонецНазначение
Train6 сентября 202619 сентября 2026Обучение модели.
Val22 сентября 202624 сентября 2026Подбор параметров и локальная оценка качества.
Test26 сентября 202629 сентября 2026Предсказания для лидерборда.

Поле timestamp хранит Unix-время записи ленты в секундах, тип int32.

Как собраны выборки

Train используется целиком для обучения. Val собирается отдельно по тем же правилам, что test.

В val и test входят только выдачи, в которых все кандидаты были равномерно случайно перемешаны до показа пользователю. Целевые метки получены по обратной связи после этих показов.

Сборщик применяет следующие правила:

  1. Оставляет кандидатов с исходной позицией rank <= 300; нумерация позиций начинается с 0.
  2. Формирует бинарную метку по наличию события из целевого набора.
  3. Оставляет ленты как минимум с пятью кандидатами и хотя бы одним положительным примером.

В публичных val и test порядок кандидатов дополнительно перемешивается одной общей перестановкой их полей. Соответствие между объявлениями, признаками, индексами эмбеддингов и метками сохраняется. Исходные позиции доступны только в train, в колонке pos; после фильтрации в них могут быть пропуски.

Структура архива

competition/
├── readme.md
├── sample_submission.parquet
├── train/
│   ├── impressions/
│   │   ├── part-*.parquet
│   │   └── _SUCCESS
│   └── item_embeddings/
│       ├── data.memmap
│       └── data.meta
├── val/
│   ├── impressions/
│   │   ├── part-*.parquet
│   │   └── _SUCCESS
│   └── item_embeddings/
│       ├── data.memmap
│       └── data.meta
└── test/
    ├── impressions/
    │   ├── part-*.parquet
    │   └── _SUCCESS
    └── item_embeddings/
        ├── data.memmap
        └── data.meta
Файл или папкаСодержимое
impressions/part-*.parquetЛенты с признаками; в train и val также содержат метки. Сжатие ZSTD. Для чтения полной выборки нужны все её Parquet-файлы.
impressions/_SUCCESSПустой служебный маркер успешной записи.
item_embeddings/data.memmapБинарная матрица эмбеддингов объявлений типа int8, форма (N, 128), порядок C.
item_embeddings/data.metaJSON с dtype, shape и order матрицы.
sample_submission.parquetОдна строка для каждого кандидата test; оценки заполнены нулями.

Ленты и признаки

list<T> означает массив значений типа T. Число кандидатов M и длина истории H могут различаться между лентами; 0 <= H <= 256.

КолонкаТипРазмер в строкеОписание
feed_idint32СкалярУникальный идентификатор ленты. Не пересекается между train, val и test.
timestampint32СкалярUnix-время записи ленты в секундах.
user_idint32СкалярОбезличенный идентификатор пользователя. Нумерация общая для всех частей датасета.
category_idlist<int8>MКод категории каждого кандидата. Словарь общий с history__category_id во всех частях датасета.
f1list<float32>MНормализованный вещественный признак № 1.
f2list<float32>MНормализованный вещественный признак № 2.
f3list<float32>MНормализованный вещественный признак № 3.
f4list<float32>MНормализованный вещественный признак № 4.
f5list<float32>MНормализованный вещественный признак № 5.
poslist<int16>MИсходная позиция кандидата, нумерация с 0. Есть только в train; после фильтрации позиции могут содержать пропуски.
targetlist<int8>MЦелевая метка кандидата: 1 — зафиксировано целевое действие, 0 — не зафиксировано. Есть только в train и val; это метка для обучения и оценки, а не входной признак модели.
item_id__embedding_idxlist<int32>MИндекс строки эмбеддинга кандидата в таблице item_embeddings/data.memmap этой части датасета. -1 означает отсутствие эмбеддинга.
item_idlist<int32>MОбезличенный идентификатор товара. Нумерация общая для кандидатов и истории во всех частях датасета.
user_embeddinglist<int8>128Эмбеддинг пользователя.
history__item_idlist<int32>HОбезличенные идентификаторы товаров из истории пользователя.
history__category_idlist<int8>HКоды категорий товаров из истории. Используется тот же словарь, что и в category_id.
history__event_typelist<int8>HКатегориальный код типа события пользователя.
history__event_sourcelist<int8>HКатегориальный код источника события пользователя.
history__item_id__embedding_idxlist<int32>HИндексы эмбеддингов товаров из истории в таблице item_embeddings/data.memmap этой части датасета. -1 означает отсутствие эмбеддинга.

Все массивы длины M описывают кандидатов в одинаковом порядке. Например, item_id[i], f1[i], category_id[i] и target[i] относятся к одному объявлению. При разворачивании ленты в строки эти массивы нужно разворачивать совместно.

target — метка для обучения и оценки, а не входной признак модели. Положительный пример означает наличие хотя бы одного события из целевого набора. В сборщике все события этого набора имеют вес 1; число совершённых действий не увеличивает метку.

Идентификаторы и категории

Идентификаторы пользователей и объявлений заменены целочисленными номерами. Нумерация объявлений общая для кандидатов и истории во всех выборках. Пользователи имеют отдельное пространство идентификаторов. Положительные значения обозначают известные объекты, 0 зарезервирован для отсутствующего ID.

feed_id уникален во всём датасете и не пересекается между train, val и test. Это не означает, что пользователи или объявления обязательно различаются между выборками.

Категории кандидатов и истории используют общий словарь. Типы и источники событий также закодированы согласованно между выборками. 0 обозначает неизвестное или отсутствующее значение. Коды событий не являются исходными номерами событий Авито.

Признаки f1–f5 уже нормализованы. Преобразования числовых признаков обучены только на train и применены к val и test без повторного обучения. Отдельные файлы энкодеров для чтения датасета не нужны.

История пользователя

Поля history__* содержат до 256 событий, упорядоченных от новых к старым. Все массивы истории одной ленты имеют одинаковую длину H; элементы с одинаковым индексом описывают одно событие.

История может быть пустой. Кандидаты и история имеют отдельные массивы: M и H не обязаны совпадать. Эмбеддинг пользователя относится ко всей ленте и всегда содержит 128 компонент.

Эмбеддинги объявлений

Каждая выборка имеет собственную таблицу эмбеддингов item_embeddings/data.memmap. Для одного объявления индексы в train, val и test могут различаться, хотя item_id остаётся общим.

Поля item_id__embedding_idx и history__item_id__embedding_idx указывают на строки таблицы соответствующей выборки. Индексы начинаются с 0. Значение -1 означает отсутствие эмбеддинга: его нельзя использовать как индекс NumPy, иначе будет прочитана последняя строка таблицы.

Перед вычислением скалярного произведения, нормы и других операций переводите int8 в float32, чтобы избежать переполнения.

Пример чтения

Пример читает одну ленту train и эмбеддинги её кандидатов. NumPy memmap позволяет обращаться к отдельным строкам матрицы без загрузки всей таблицы в оперативную память.

import json
from pathlib import Path

import numpy as np
import polars as pl

split = Path("competition/train")
feed = (
    pl.scan_parquet(str(split / "impressions/part-*.parquet"))
    .head(1)
    .collect()
    .row(0, named=True)
)

embedding_dir = split / "item_embeddings"
meta = json.loads((embedding_dir / "data.meta").read_text())
embeddings = np.memmap(
    embedding_dir / "data.memmap",
    dtype=meta["dtype"],
    mode="r",
    shape=tuple(meta["shape"]),
    order=meta["order"],
)

indices = np.asarray(feed["item_id__embedding_idx"], dtype=np.int64)
present = indices >= 0
candidate_vectors = np.zeros((len(indices), 128), dtype=np.float32)
candidate_vectors[present] = embeddings[indices[present]].astype(np.float32)
user_vector = np.asarray(feed["user_embedding"], dtype=np.float32)

Локальная валидация

Для подбора параметров используйте готовую val-выборку: она содержит target и собрана по тем же правилам, что test. Оценивайте NDCG внутри каждого feed_id, затем усредняйте по лентам с одинаковым весом.

В данных одной ленты признаки и метки согласованы по индексам массивов. После разворачивания в строки сохраняйте связь (feed_id, item_id) с оценкой и меткой.

Эталонные правила метрики описаны в «Описание». Скрипт calculate_metrics.py предназначен для закрытых тестовых ответов с колонкой leaderboard_split; к публичной val-выборке без подготовки данных он напрямую не применяется.

Бейзлайны

Скачайте бейзлайны с Яндекс Диска: catboost_baseline.py, neural_baseline.py, calculate_metrics.py, pyproject.toml и uv.lock.

После получения исходников создайте окружение и активируйте его. Все дальнейшие команды выполняются из папки со скачанными скриптами, pyproject.toml и uv.lock; --data указывает на корень распакованного competition/.

cd /path/to/baselines
uv sync --locked --no-config --default-index https://pypi.org/simple
source .venv/bin/activate

python catboost_baseline.py train \
    --data /path/to/competition --output runs/catboost-01
python catboost_baseline.py predict \
    --data /path/to/competition --model runs/catboost-01/model.cbm \
    --output runs/catboost-01/submission.parquet

python neural_baseline.py --device cuda train \
    --data /path/to/competition --output runs/neural-01
python neural_baseline.py --device cuda predict \
    --data /path/to/competition --model runs/neural-01/model.pt \
    --output runs/neural-01/submission.parquet

Все зависимости устанавливаются из публичного PyPI; доступ к внутреннему PyPI Авито не требуется.

CatBoost по умолчанию обучается на GPU. Для Transformer параметр --device задаётся перед подкомандой; для CPU используйте --device cpu. Оба решения читают полный train и val по умолчанию и сохраняют предсказания всех кандидатов test.

Формат сабмита

sample_submission.parquet содержит:

КолонкаТипОписание
feed_idint32Тестовая лента.
item_idint32Объявление-кандидат.
scorefloat32Предсказанная релевантность.

Замените нулевые оценки своими предсказаниями. Нужны все пары из шаблона, без пропусков, дополнительных пар и дубликатов. Оценки должны быть конечными и не содержать пустых значений.

Чем выше score, тем выше кандидат в ленте. Порядок строк в файле не важен. Разделение Public/Private выполняется по времени ленты примерно в пропорции 30/70; итоговая метрика — NDCG.

Глоссарий

ТерминЗначение
ЛентаНабор кандидатов для одного рекомендательного показа, определяемый feed_id.
КандидатОбъявление, которому модель должна присвоить оценку внутри ленты.
ЭмбеддингЧисловой вектор пользователя или объявления размерности 128.
ИсторияДо 256 событий пользователя, от новых к старым.
TargetБинарная метка наличия целевого действия.
ScoreПредсказанная оценка, определяющая порядок кандидатов.
NDCGМетрика качества ранжирования.
Public / PrivateБолее ранняя и более поздняя части тестовых лент для промежуточного и итогового лидербордов.

Our website uses cookies, including web analytics services. By using the website, you consent to the processing of personal data using cookies. You can find out more about the processing of personal data in the Privacy policy