Один объект для sklearn predict: почему список признаков не равен батчу из одной строки
У сервиса два входа: пакет заявок и одна заявка из формы. Пакет работает, а одиночный запрос падает с сообщением Expected 2D array. Разработчик передал [возраст, сумма], то есть одномерный список из двух чисел. Для scikit-learn это не один объект с двумя полями: методы предсказания ждут матрицу «объекты × признаки», включая случай одного объекта.
Добавьте ось объектов, а не ось признаков
Форма одного объекта с двумя признаками — (1, 2), а двух объектов с одним признаком — (2, 1). Ошибочное исправление через reshape(-1, 1) меняет смысл входа. Перед вызовом модели API может проверить ожидаемое число признаков и строить строку в согласованном порядке полей. В примере ниже модель получает один числовой признак; поэтому различие видно без дополнительных преобразований.
import numpy as np
from sklearn.linear_model import LinearRegression
model = LinearRegression().fit([[1.0], [2.0], [3.0]], [10.0, 20.0, 30.0])
value = [4.0]
try:
model.predict(value)
except ValueError as exc:
print("1D отклонён:", "2D array" in str(exc))
else:
raise AssertionError("Ожидалась ошибка формы")
one_row = np.asarray(value, dtype=float).reshape(1, -1)
prediction = model.predict(one_row)
print("форма:", one_row.shape, "ответ:", round(float(prediction[0]), 1))
assert one_row.shape == (1, model.n_features_in_)
assert np.isclose(prediction[0], 40.0)Одномерный вход отклонён; после добавления оси объектов форма стала (1, 1), ответ — 40,0. Для нескольких признаков форма будет (1, n_features). Если вы принимаете JSON-массив, договоритесь, означает ли верхний уровень одну заявку или список заявок; иначе запрос [4, 5] двусмыслен даже до sklearn.
Если вход — DataFrame с именами полей, одна строка всё равно остаётся таблицей из одной строки. Это удобно для смешанных числовых и категориальных признаков: pd.DataFrame([payload]) сохраняет имена колонок. Но скобки вокруг payload важны: pd.DataFrame(payload) с отдельными скалярами может не создать нужную строку. Проверьте точную форму перед predict, а порядок и состав колонок — отдельно. При переходе от одного объекта к batch путь должен создавать такие же строки и соединять их по id.
Зафиксируйте границу в тесте API
Проверьте пустой батч, одну строку и несколько строк. Ошибку числа полей возвращайте клиенту до модели с понятным именем поля, а не как необработанное исключение NumPy. Это отдельная задача от порядка столбцов: здесь меняется размерность массива. Когда формат входа принят, тест на одну строку защищает самый частый путь вызова модели из формы.
В API не стоит молча превращать произвольный плоский список в матрицу. Если модель ждёт три признака, запрос из трёх чисел можно считать одной строкой, но запрос из шести чисел может означать два объекта или испорченный объект. Выберите один JSON-формат, например {"instances": [[...], [...]]}, и проверяйте вложенность. Для одиночного сценария сформируйте пакет из одной строки явно; тогда код предсказания и тесты остаются общими с пакетным путём.
В курсе «Data Scientist: от данных до деплоя моделей» модель проходит путь до inference API с проверками контракта и релиза. Посмотрите программу курса, если хотите проверить модель на границе реальных запросов.
Продолжить на практике
- Data Scientist: от данных до деплоя моделей ↗
Практический курс по Data Science: от постановки ML-задачи и работы с данными до inference API, CI/CD и мониторинга моделей в продакшне. Вы пройдёте EDA, feature engineering, обучение и оценку моделей, experiment tracking, error analysis и deployment — чтобы собирать полноценный рабочий контур вокруг ML-решения.
