Валидация, верификация и калибровка
Модель выдала ответ. Но прежде чем ему верить, нужно ответить на два разных вопроса: «правильно ли я её запрограммировал?» и «похожа ли она вообще на реальность?». Это не одно и то же — и путать их дорого.
Верификация — проверка, что модель запрограммирована правильно (делает то, что задумано). Валидация — проверка, что модель достаточно хорошо соответствует реальному миру.
Разницу легко запомнить так: верификация отвечает на вопрос «решаем ли мы уравнения правильно?», а валидация — «правильные ли уравнения мы вообще решаем?». Можно безупречно, без единого бага, запрограммировать совершенно неадекватную модель — она пройдёт верификацию и провалит валидацию. И наоборот: правильная по сути модель с ошибкой в коде даст чепуху.
Зачем это разделение нужно. Когда прогноз расходится с данными, оно подсказывает, где искать причину: в коде (ищите баг — это верификация) или в самих допущениях модели (модель не отражает реальность — это валидация). Без этого различения отладка превращается в блуждание.
«Все модели неверны, но некоторые полезны»
Эту фразу сформулировал статистик Джордж Бокс. Её смысл не пораженческий, а трезвый: любая модель — это упрощение, она заведомо что-то отбрасывает, поэтому буквально «верной» быть не может. Вопрос не в том, верна ли модель, а в том, достаточно ли она полезна для конкретной задачи. Карта в масштабе 1:1 бесполезна именно потому, что точна; полезная карта намеренно неточна.
«Все модели неверны, но некоторые полезны». — Джордж Бокс
Калибровка: подбираем параметры по данным
Часто структура модели известна (например, экспоненциальный рост), но конкретное значение параметра — нет. Калибровка — это поиск такого значения параметра, при котором модель максимально близка к наблюдаемым данным. Самый прямолинейный способ — перебрать сетку значений и выбрать то, что даёт минимальную ошибку.
Калибровка — подбор параметров модели по реальным данным так, чтобы предсказания модели были как можно ближе к наблюдениям.
У нас есть пять наблюдений роста некоторой величины. Модель — простой экспоненциальный рост N → N·(1 + r). Нужно найти r. Мерой «близости» возьмём сумму квадратов отклонений (метод наименьших квадратов): чем она меньше, тем лучше параметр.
observed = [100, 150, 225, 338, 506] # реальные наблюдения
def predict(r, steps):
N = 100.0
out = [N]
for _ in range(steps):
N = N * (1 + r)
out.append(round(N))
return out
best_r = None
best_err = None
for ri in range(1, 100):
r = ri / 100
pred = predict(r, 4)
err = sum((p - o) ** 2 for p, o in zip(pred, observed))
if best_err is None or err < best_err:
best_err = err
best_r = r
print(f"Лучшее r: {best_r}")
print(f"Предсказание при r={best_r}:", predict(best_r, 4))
print(f"Наблюдения:", observed)
Вывод:
Лучшее r: 0.5 Предсказание при r=0.5: [100.0, 150, 225, 338, 506] Наблюдения: [100, 150, 225, 338, 506]
Перебор нашёл r = 0.5: при темпе роста 50% за шаг модель воспроизводит наблюдения почти идеально (100 → 150 → 225 → 338 → 506). Это и есть калибровка: мы не угадывали параметр, а вывели его из данных, минимизируя ошибку.
Как работает под капотом
Цикл for ri in range(1, 100) перебирает r от 0.01 до 0.99 с шагом 0.01 — это и есть «сетка». Для каждого кандидата мы строим прогноз predict(r, 4) и считаем сумму квадратов расхождений с наблюдениями. Сравнение if err < best_err запоминает лучший результат. Возведение в квадрат не случайно: оно делает ошибку всегда положительной и сильнее штрафует крупные промахи, поэтому минимум суммы квадратов — устойчивая цель оптимизации. Это упрощённый ручной вариант того, что в больших задачах делают численные оптимизаторы.
Переобучение: ловушка лишних параметров
Здесь подстерегает главная опасность калибровки — переобучение. Если у модели слишком много свободных параметров, она подстроится не под закономерность, а под случайный шум в данных. Крайний случай: модель с 10 параметрами можно идеально провести через 10 точек — ошибка будет нулевой. Но такая модель запомнила именно эти точки, включая их случайные отклонения, и на новых данных провалится.
Мало параметров: модель ловит тренд, чуть мажет по точкам — но прогноз надёжен
Много параметров: модель проходит через ВСЕ точки точно — но это запомненный шум
идеально на обучении, бесполезно на прогнозе
Именно поэтому простой моделью с одним параметром r, которая хорошо ложится на данные, доверяют больше, чем сложной модели с десятком параметров, лёгшей идеально. Простота — защита от переобучения.
Частые ошибки
- Считать верификацию и валидацию одним и тем же. Безбаговый код не гарантирует адекватности модели реальности, и наоборот.
- Гнаться за нулевой ошибкой на обучении. Идеальная подгонка под данные — почти всегда признак переобучения, а не качества.
- Добавлять параметры ради улучшения подгонки. Каждый новый параметр повышает риск поймать шум; добавляйте их, только если есть содержательное обоснование.
- Калибровать и проверять на одних и тех же данных. Честная проверка — на отложенной выборке, которую модель не видела при калибровке.
- Забывать, что модель — упрощение. Ожидать от модели буквальной «верности» бессмысленно; цель — полезность (Бокс).
Итоги
- Верификация — «правильно ли запрограммировано», валидация — «соответствует ли реальности»; это разные проверки.
- «Все модели неверны, но некоторые полезны» (Бокс): цель не истинность, а пригодность для задачи.
- Калибровка — подбор параметров по данным минимизацией суммы квадратов ошибок; перебор сетки нашёл r = 0.5.
- Переобучение: модель с избытком параметров идеально ложится на точки, но запоминает шум и проваливает прогноз.
- Простая модель, неплохо ложащаяся на данные, надёжнее сложной, лёгшей идеально.