Batch-инференс перемешал строки: как сохранить связь прогноза с id
Ночной расчёт скоринга отбирает клиентов без действующего предложения, сортирует их по времени обновления и передаёт признаки модели. Предсказания приходят массивом той же длины, что отфильтрованный пакет. Ошибка возникает, когда массив записывают рядом с исходным списком клиентов по номеру строки: часть вероятностей оказывается у чужих id. Метрика модели в ноутбуке при этом не меняется; ломается доставка результата.
Позиция массива действует только внутри переданного пакета
predict_proba возвращает результат в порядке полученных строк, а не в порядке старой таблицы. Поэтому сначала сформируйте конкретный пакет с id, затем отдельно выделите признаки и прикрепите ответы обратно к этому же пакету. Не полагайтесь на сохранённый индекс pandas: после reset_index, сериализации или передачи через очередь его семантика может исчезнуть. Явный бизнес-ид надёжнее.
В примере три заявки пришли в одном порядке, но одна отфильтрована, а две сортируются по приоритету. Функция модели здесь заменена простым вычислением, чтобы видна была именно связь строк, а не качество алгоритма.
import pandas as pd
requests = pd.DataFrame([
{"id": "A-10", "score_feature": 2, "eligible": True, "priority": 1},
{"id": "B-20", "score_feature": 9, "eligible": False, "priority": 9},
{"id": "C-30", "score_feature": 7, "eligible": True, "priority": 3},
])
batch = requests.loc[requests["eligible"]].sort_values("priority", ascending=False).copy()
features = batch[["score_feature"]]
probabilities = features["score_feature"].to_numpy() / 10
result = pd.DataFrame({"id": batch["id"].to_numpy(), "probability": probabilities})
print(result.to_dict("records"))
assert result.set_index("id").loc["C-30", "probability"] == 0.7
assert result.set_index("id").loc["A-10", "probability"] == 0.2
assert "B-20" not in result["id"].tolist()Ответ для C-30 равен 0,7, для A-10 — 0,2; B-20 в пакет не вошёл. Проверка не зависит от случайного индекса таблицы. Если прогноз запускается параллельными частями, сохраняйте вместе с каждой частью исходный id и версию задания. Конкатенация ответов по времени завершения частей не обязана повторять порядок входа.
В журнале задания полезно записывать количество входных объектов до фильтра, после фильтра, после предсказания и после записи результата. Эти четыре числа позволяют быстро локализовать исчезнувшие строки. Если они равны, это ещё не доказывает правильность соответствия: перестановка сохраняет объём. Поэтому добавьте выборочную проверку пары «id → признаки → прогноз», а для критичных решений сохраняйте эту тройку в аудите. Особенно часто перестановка возникает после merge с неуникальным ключом или после параллельной обработки, где части заканчиваются не в порядке запуска.
Перед записью проверьте кардинальность
Для пакетного задания полезны три простые инварианта: id в результате уникальны, множество id равно множеству выбранных заявок, число ответов равно числу входных строк. Если один клиент может иметь несколько заявок, ключом должна быть пара «id заявки + версия расчёта», а не только id клиента. До загрузки в CRM проверьте несколько известных объектов и журналируйте хеш пакета: это помогает отделить ошибку маршрутизации от ошибки модели.
Похожая внешне проблема с порядком столбцов описана в разборе схемы входных признаков. Здесь столбцы могут быть совершенно правильными, а перепутаны именно объекты.
Есть ещё ловушка повторного запуска. Если ночное задание упало после записи половины результатов, повторная отправка того же пакета может создать два прогноза для одной заявки. Задайте ключ идемпотентности из id заявки и версии задания; запись должна обновлять ту же строку либо явно отклонять дубль. Если скоринг пересчитывается каждый день, дата расчёта входит в ключ, иначе вчерашний ответ может перезаписать сегодняшний. Так вы сохраняете не только правильное соответствие строк, но и историю решений.
В курсе «Data Scientist: от данных до деплоя моделей» есть batch-инференс, проверки data pipeline и работающий контур доставки прогноза. Откройте программу курса, если хотите пройти этот путь на проекте от таблицы до сервиса.
Продолжить на практике
- Data Scientist: от данных до деплоя моделей ↗
Практический курс по Data Science: от постановки ML-задачи и работы с данными до inference API, CI/CD и мониторинга моделей в продакшне. Вы пройдёте EDA, feature engineering, обучение и оценку моделей, experiment tracking, error analysis и deployment — чтобы собирать полноценный рабочий контур вокруг ML-решения.
