Фолды разного размера: почему средняя MAE не равна общей
В одном фолде сто объектов, в другом десять. Среднее двух MAE придаёт им одинаковый вес. Ошибка по объединённым прогнозам даёт каждому объекту одинаковый вес. Оба расчёта допустимы, но описывают разные вопросы.
Выбрать, что имеет одинаковый вес
Обычная средняя по фолдам рассматривает каждый проверочный набор как единицу. Это может быть нужно, если фолды — разные равноправные площадки. Общая MAE по строкам считает равноправным каждый объект. При разных размерах фолдов эти цели расходятся.
Для MAE объединённый результат восстанавливается из ошибок фолдов, взвешенных числом объектов, когда у всех строк одинаковый исходный вес. Это следствие аддитивности суммы абсолютных ошибок. Для нелинейных метрик нельзя автоматически переносить то же правило.
Сверить оба расчёта на одном наборе прогнозов
В первой группе две ошибки по единице, во второй одна ошибка 10. Средняя двух групповых MAE равна 5.5, а ошибка трёх объектов — 4. Веса определяют различие полностью.
Ниже используем готовые out-of-fold прогнозы: каждая строка должна быть получена моделью, которая не обучалась на этой строке. Расчёт метрики не проверяет это происхождение автоматически, поэтому manifest фолдов хранится отдельно.
import numpy as np
from sklearn.metrics import mean_absolute_error
y = np.array([10., 20., 30.])
pred = np.array([11., 19., 40.])
fold = np.array([0, 0, 1])
fold_ids = np.unique(fold)
mae = np.array([mean_absolute_error(y[fold == f], pred[fold == f]) for f in fold_ids])
sizes = np.array([(fold == f).sum() for f in fold_ids])
macro_fold = mae.mean()
pooled = mean_absolute_error(y, pred)
weighted = np.average(mae, weights=sizes)
print({"fold_MAE": mae.tolist(), "fold_sizes": sizes.tolist(),
"mean_of_folds": macro_fold, "pooled_MAE": pooled})
assert macro_fold == 5.5 and pooled == 4
assert weighted == pooledЧисло 5.5 описывает среднюю ошибку равноправной группы, число 4 — среднюю ошибку объекта. Нельзя объявить один результат неверным, не зная цели отчёта. Но называть оба «MAE всех прогнозов» нельзя.
Проверить покрытие out-of-fold таблицы
У каждого исходного объекта должен быть понятный статус: проверен один раз, несколько раз или не проверен. В repeated CV один объект участвует в нескольких проверках, и простое объединение строк задаёт дополнительный вес. При временной оценке начальный обучающий период может вообще не иметь прогноза.
Сохраняйте id объекта, fold_id, версию процедуры и прогноз. Проверьте повторы ключей и совпадение y с исходной таблицей по id. Иначе ошибка выравнивания даст аккуратные, но бессмысленные средние.
Если используете sample_weight, для восстановления общей MAE нужны суммы весов, а не число строк. Правило должно быть одинаковым на уровне фолда и общего расчёта. Для группового теста полезно показывать обе картины: нагрузку объектов и качество по равноправным группам.
Разброс MAE по фолдам сохраняйте рядом со средним. Один тяжёлый период или площадка требует предметного анализа, даже если объединённый балл выглядит приемлемо. Выбор весов не должен скрывать такой срез.
Закрепить на практике
В бесплатном уроке MAE, MSE и RMSE вы посчитаете ошибку по фактам и прогнозам. После этого сравните её объединение по фолдам и выберите единицу усреднения для своего отчёта. Откройте бесплатный урок и задачи. Полная последовательность тем — в бесплатном курсе.
Продолжить на практике
- Машинное обучение с нуля на Python: первая модель ↗
Бесплатный курс машинного обучения на Python: обучите первую модель в scikit-learn, проверьте её качество и решите 106 задач в браузере.
