# Benchmarks #
**Benchmarks** -- Это инструмент для проведения экспериментов по улучшению качества модели. Проведение эксперимента состоит из следующих шагов:
1. Загрузить все признаки из YT
2. Трансформировать каждый признак в соответствии со своим правилом
3. Обучить модель на кросс-валидации
4. Посчитать метрики качества
5. Записать результат в дин. таблицу на YT, а также в Startrek

Бенчмарк -- это ни что иноое, как просто совокупность из натурального числа экспериментов. Далее уже система визуализации должна сама определить, как посчитать и нарисовать качество бенчмарков (например путем усреднения их метрик).

## Особенности работы ##
- Все таблицы с признаками кэшируются. Это сделано для 100% воспроизводимости эксперимента. Входы копируются в специальную директорию. Это не вызовет рост потребления квоты, т.к. чанки у таблиц будут общими. Если же исходная таблица будет изменена, то ее старая версия сохранится в кэше.
При этом выполняются следующие условия:
1. Все ссылки сначала разрешаются в таблицы
2. Ключом кэширования является (yt_path, modification_time)
3. Кэширование -- замкнутая операция (кэш от кэша есть он сам)

- Трансформация признаков нужна, чтобы из формата хранения перевести их в формат, подходящий для модели. Например если это категориальный признак, то можно его закодировать с помощью one hot encoding.

- Кросс-валидация для обучения единая и она зафиксирована внутри кода

- Все таблицы с признаками должны содержать колонку external_id

- Метрики считаются отдельно на всех объектах и объектах "клик стрима" (это подмножество указывается отдельным параметром)

- Перед запуском конфиг превращается в "расширенный конфиг". В "расширенном конфиге" все пути заменяются на пути до кэшей и добавляется ревизия

## Разбор полей конфига ##
```python
{
    "root": "",  # Опциональный параметр. Префикс для таблиц на YT
    "cs_tables": [],  # Список из таблиц кликстрима. Пересечение их external_id есть подмножество, на котором будут рассчитаны cs метрики
    "features": [
        {
            "params": {},  # параметры, который нужно передать в конструктор трансформера
            "table_path": "",  # Путь до таблицы. Если начинается с "//", то это абсолютный путь. Если с "/", то путь относительно root. Если нет слэшей, то это alias (псеводним для таблицы)
            "transformer": ""  # Название класса-трансформера
        }
    ],  # описание признаков
    "model": {
        "model": "",  # Название модели
        "params": {}  # Параметры, передаваемые в конструктор модели
    },
    "revision": 6130418,  # Ревизия. Проставляется автоматически.
    "target": {
        "table_path": "",  # Путь до таблицы с таргетами
        "target_col": ""  # Колонка с таргетами. По-умолчанию target
    },
    "ticket": "",  # Тикет, куда сообщать результаты эксперимента
    "metrics": []  # Названия метрик, которые необходимо рассчитать. По-умолчанию стандартные метрики бинарной классификации
}
```

## Пример запуска ##
```python
from datacloud.ml_utils.benchmark_v2.benchmark import Experiment
exp = Experiment({
    "cs_tables": [
        "//home/x-products/penguin-dvier-dev/cache/features_dssm_2019-12-17T05:56:44.632023Z",
        "//home/x-products/penguin-dvier-dev/cache/features_normed_s2v_2019-12-17T06:07:13.100838Z"
    ],
    "features": [
        {
            "params": {},
            "table_path": "//home/x-products/penguin-dvier-dev/cache/features_dssm_2019-12-17T05:56:44.632023Z",
            "transformer": "DecodeAndFillNanToMeanAndHit"
        },
        {
            "params": {},
            "table_path": "//home/x-products/penguin-dvier-dev/cache/features_normed_s2v_2019-12-17T06:07:13.100838Z",
            "transformer": "DecodeAndFillNanToMeanAndHit"
        }
    ],
    "model": {
        "model": "LogisticRegression",
        "params": {
            "C": 0.25,
            "max_iter": 1000,
            "solver": "lbfgs"
        }
    },
    "target": {
        "table_path": "//home/x-products/penguin-dvier-dev/cache/glued_2019-12-17T06:07:58.153700Z",
        "target_col": "target_APP_DECISION"
    },
    "ticket": "XPROD-1667"
})
exp.run()
```

```exp.run('nirvana')``` - Для запуска в Нирване
```exp.run('local')``` - Для локального запуска

### Запрос определенного железа в Нирване ###
```python
import vh
exp.run('nirvana', vh.HardwareParams(
    max_ram=64 * 1024,
    cpu_guarantee=100,
    gpu_count=1,
    gpu_max_ram=7000
))
```


## Полезные ссылки ##
- [Кэши](https://yt.yandex-team.ru/hahn/navigation?path=//home/x-products/penguin-dvier-dev/cache&)
- [Конфиги экспериментов](https://yt.yandex-team.ru/hahn/navigation?offsetMode=key&path=//home/x-products/penguin-dvier-dev/cache/exps_storage&)
- [Дэшборд с экспериментами Homecredit](https://dash.yandex-team.ru/3ztjegn6pcbs0?state=d30e54e3789)
- [Дэшборд с экспериментами TCS](https://dash.yandex-team.ru/3ztjegn6pcbs0?state=6ef55eab744)