Формат
Формат отчёта и набора проверок
Это описание файлов, которые сайт сохраняет на ваше устройство. HTTP-API нет, запросы никуда не отправляются.
1. Входной CSV
Схема образца в порядке колонок. Пустое значение — поле без символов. Числа в CSV используют точку; при разделителе «;» принимается и десятичная запятая.
| колонка | тип | диапазон эталона | допустимые значения |
|---|---|---|---|
order_id | строка | — | уникальный идентификатор; распределение не сравнивается |
distance_km | число | 0,8 … 30,7 | расстояние доставки, км |
items | целое | 1 … 25 | число позиций в заказе |
weight_kg | число | 0,5 … 23,3 (7 пустых) | вес заказа, кг; допускается пустое значение |
zone | категория | — | центр, север, юг, запад, восток |
slot | категория | — | утро, день, вечер |
is_express | категория | — | 0, 1 |
eta_min | целое | 5 … 82 | оценка времени доставки, мин |
«Диапазон эталона» — фактические минимум и максимум 600 строк эталона. Диапазоны набора проверок по умолчанию (0–60, 1–50, 0–50, 5–240) заданы по смыслу поля, а черновик берёт min/max эталона ±10 % размаха.
Ограничения ввода: до 5000 строк и 300 КБ; разделитель «,» или «;»; первая строка — заголовок. Поля в двойных кавычках с экранированием "", переводы строк CRLF или LF.
2. Набор проверок JSON
Формат mlpipeline-suite/1. Кнопка «Копировать набор проверок» на столе выдаёт текущий набор.
{
"format": "mlpipeline-suite/1",
"status": "default",
"expectations": [
{"id": "row_count", "params": {"min": 300, "max": 5000}},
{"id": "schema"},
{"id": "unique", "column": "order_id"},
{"id": "completeness", "params": {"weight_kg": 98, "rest": 100}},
{"id": "numeric", "columns": ["distance_km", "items", "weight_kg", "eta_min"]},
{"id": "range", "params": {
"distance_km": [0, 60], "items": [1, 50],
"weight_kg": [0, 50], "eta_min": [5, 240]}},
{"id": "in_set", "params": {
"zone": ["центр","север","юг","запад","восток"],
"slot": ["утро","день","вечер"], "is_express": ["0","1"]}}
],
"thresholds": {"notable": 0.10, "strong": 0.25, "share_rule": 0.50}
}
3. Отчёт JSON
Формат mlpipeline-batch-report/1. В отчёте только агрегаты: нет значений строк и нет значений order_id. Частые значения (top) приводятся только для категорий схемы zone, slot, is_express; для колонок вне схемы — только счётчики (type: "extra", count, missing, distinct).
| поле | значение |
|---|---|
format | mlpipeline-batch-report/1 |
sample | true для образца, false для вставленного CSV |
generated_in_browser | всегда true |
note | пометка об образце или о данных пользователя |
reference | {rows, seed, profile} |
batch | {source, label, rows, seed|null, profile} |
suite | набор проверок (см. раздел 2) |
thresholds | {notable, strong, share_rule} |
checks[] | {id, column, expectation, params, observed, status} |
drift[] | {column, method:"psi", bins:[{label, reference_share, batch_share}], score, level} |
drift_share, dataset_drift | доля дрейфа и признак дрейфа набора |
verdict | {code:"pass"|"review"|"stop", label, reasons} |
run, fingerprint | номер прогона и {value, algo: "sha256" | "fnv1a"} |
4. Расчёт PSI
PSI = Σ (b − r) · ln(b / r) r = max(доля эталона в бине, 0,0001) b = max(доля партии в бине, 0,0001)
Числовые бины — децили эталона (p10…p90), совпадающие границы удаляются. Индекс бина — bisect_right(edges, v), поэтому значение, равное границе, идёт в верхний бин. Для категорий бинами служат значения эталона по убыванию частоты (при равенстве — по коду символа) плюс общий бин «другое». Пустой бин заменяется долей 0,0001. Колонка, в которой меньше 100 непустых значений партии, помечается «мало данных» и в долю дрейфа не входит.
5. Уровни и вердикт
Уровень по PSI: меньше порога «заметно» — «в пределах»; от «заметно» и меньше «сильно» — «заметно»; от «сильно» — «сильно». Доля дрейфа — колонки с уровнем не ниже «заметно» среди оценённых (7 при полной схеме, order_id не входит). Набор сдвинут, если доля не меньше порога набора.
Вердикт: любая нарушенная проверка — «Остановить»; иначе любое «сильно» или дрейф набора — «Разобрать»; иначе — «Передать в обучение», а колонки «заметно» перечисляются как замечания. На столе вердикт всегда сопровождается строкой «Учебный вердикт по правилам стола — решение за вами»; в JSON — code, label, reasons (причины с именами проверок и колонок), а пометка об образце — в note.
6. Отпечаток прогона
Отпечаток — SHA-256 канонического JSON отчёта (ключи отсортированы рекурсивно) без полей run и fingerprint, через crypto.subtle. Если crypto.subtle недоступен, используется FNV-1a 32-бит с пометкой «FNV-1a (без crypto.subtle)». Одинаковые входные данные дают одинаковый отпечаток; изменение параметров его меняет.
7. Параметры генерации образца
Генератор детерминированный: PRNG mulberry32(seed), нормальные значения — Box–Muller из того же потока (два равномерных на одно нормальное). Порядок розыгрыша на строку фиксирован: distance (нормальное), items (экспоненциальное), фактор weight, тест пустого weight, zone, тест «пригород», slot, is_express, eta (нормальное), тест отрицательного items.
Эталон: seed 11, 600 строк, order_id «R-00001»…«R-00600». Формулы:
distance_km = clamp(exp(N(1,9; 0,6)), 0,3; 40), округление до 0,1
items = clamp(1 + floor(Exp(среднее 4)), 1, 30)
weight_kg = round(items · 0,8 · (0,6 + 0,9·U), 1), не больше 45; пусто с p=0,01
zone = центр .34 / север .18 / юг .18 / запад .15 / восток .15
slot = утро .30 / день .42 / вечер .28
is_express = 1 с p=0,22, иначе 0
eta_min = clamp(round(12 + 2,1·distance + 0,7·items − 6·is_express
+ 5·[slot=вечер] + N(0;5)), 5, 240)
Сценарии: even (seed 12, 600 строк, «N-00001»…); shifted-distance (seed 13, 600 строк, distance умножается на 1,35 до расчёта eta); new-zone-gaps (seed 14, 600 строк, zone заменяется на «пригород» с p=0,18, weight_kg пусто с p=0,09); broken-export (seed 15, 140 строк, slot по-английски, weight_kg заменена на weight_g = weight_kg·1000, items отрицательны с p=0,04, 6 дублей order_id).
| сценарий | ключевые PSI | вердикт |
|---|---|---|
| Ровная партия | все PSI меньше 0,10 | Передать в обучение |
| Сдвиг расстояний | distance_km и eta_min сдвинуты, остальные в пределах | Разобрать |
| Новая зона и пропуски | zone и полнота weight_kg нарушены | Остановить |
| Сломанная выгрузка | схема, строки, уникальность, items и slot нарушены | Остановить |
Точные калиброванные значения PSI отображаются на столе после проверки и совпадают со скачанным отчётом.
8. Сценарии
| название | тип | состояние | описание |
|---|---|---|---|
| Ровная партия | Сценарий партии | Образец | 600 строк, другое зерно генератора; схема, ожидания и распределения в норме |
| Сдвиг расстояний | Сценарий партии | Образец | 600 строк; distance_km ×1,35, вслед за ним растёт eta_min; ожидания соблюдены, распределение сдвинуто |
| Новая зона и пропуски | Сценарий партии | Образец | 600 строк; около 18 % зоны «пригород» и около 9 % пустых weight_kg |
| Сломанная выгрузка | Сценарий партии | Образец | 140 строк; слоты по-английски, weight_g вместо weight_kg, отрицательные items, дубли order_id |
9. Ограничения
Метод один — PSI по бинам; многомерный дрейф и дрейф целевой переменной не рассматриваются. Пороги эвристические. Вердикт учебный. Скрипт на Python проверяет только PSI. Сверка смотрит на данные до обучения и не измеряет качество предсказаний модели.