Коэффициенты скачут, прогноз держится: как выбрать регуляризацию линейной модели по времени
Модель оценивает число обращений по рекламным показам и посещениям сайта. Оба признака растут вместе. После небольшой замены обучающего периода коэффициент показов меняет знак, а качество прогноза почти сохраняется. На презентации это выглядит как ошибка: вчера реклама увеличивала нагрузку, сегодня уменьшает. На деле несколько похожих комбинаций коэффициентов могут давать почти одинаковые ответы на наблюдаемых данных.
Регуляризация ограничивает величину коэффициентов и помогает выбрать более устойчивое решение. Но силу ограничения нельзя определять по красоте коэффициентов или качеству на обучении. Для планирования нагрузки важно, как модель переживает следующий период. Разберём подбор на последовательных отрезках, включая подготовку признаков.
Что именно ограничивает ridge
Обычная линейная регрессия уменьшает сумму квадратов ошибок. Ridge добавляет к ней alpha, умноженную на сумму квадратов коэффициентов. Большая alpha сильнее мешает модели компенсировать один огромный коэффициент другим. Свободный член обычно оставляют без такого штрафа: он задаёт общий уровень, а не влияние признака.
Масштаб здесь меняет смысл штрафа. Если показы измерены в миллионах, а посещения в штуках, одинаковый численный коэффициент означает разное влияние. Поэтому среднее и стандартное отклонение считаем на обучающем отрезке и этими же числами преобразуем следующий. Средние из будущего нельзя включать в подготовку, даже если целевая переменная ещё не использовалась.
Три отрезка вместо случайной смеси
Сначала выделим обучение, следующий период для выбора alpha и последний период для окончательной проверки. Последний открываем после выбора. Если использовать его каждый раз при изменении сетки, он превратится в ещё одну валидацию. На длинной истории лучше повторять выбор на нескольких последовательных окнах, каждый раз оставляя будущее справа от обучения.
Пример использует NumPy и действительно обучает линейную модель. Решение системы выполняет numpy.linalg.solve. Вход синтетический: два близких признака имитируют посещения и показы. Ошибку сравниваем в исходных единицах целевой переменной.
import numpy as np
rng = np.random.default_rng(17)
t = np.arange(120)
visits = 50 + 0.3*t + rng.normal(0, 5, len(t))
impressions = visits + rng.normal(0, 0.3, len(t))
X = np.column_stack([visits, impressions])
y = 4 + 1.6*visits + rng.normal(0, 4, len(t))
def fit_predict(Xtr, ytr, Xnext, alpha):
mean, scale = Xtr.mean(0), Xtr.std(0)
scale = np.where(scale == 0, 1, scale)
A = np.column_stack([np.ones(len(Xtr)), (Xtr-mean)/scale])
B = np.column_stack([np.ones(len(Xnext)), (Xnext-mean)/scale])
penalty = np.diag([0., alpha, alpha])
coef = np.linalg.solve(A.T@A + penalty, A.T@ytr)
return B@coef, coef
scores = {}
for alpha in (0.01, 0.1, 1., 10., 100.):
pred, coef = fit_predict(X[:70], y[:70], X[70:95], alpha)
scores[alpha] = float(np.abs(y[70:95]-pred).mean())
print(alpha, 'validation_MAE', round(scores[alpha], 3))
chosen = min(scores, key=scores.get)
pred, coef = fit_predict(X[:95], y[:95], X[95:], chosen)
print('chosen', chosen, 'test_MAE', round(float(np.abs(y[95:]-pred).mean()), 3))
assert np.isfinite(pred).all() and len(pred) == 25Как принять решение по таблице ошибок
Выбираем минимальную ошибку валидации, затем заново обучаем модель на первых двух отрезках. Средние и масштабы при этом тоже пересчитываем: для финального периода эти данные уже являются прошлым. В сохранённый комплект должны попасть коэффициенты, порядок столбцов и новые параметры стандартизации. Одних коэффициентов для воспроизведения ответа недостаточно.
Если несколько alpha дают близкие результаты, проверьте устойчивость на дополнительных временных окнах. Можно предпочесть более сильное ограничение, когда оно не ухудшает важные периоды и уменьшает разброс коэффициентов. Зафиксируйте правило выбора заранее: например, допустимую потерю MAE относительно лучшего варианта. Иначе симпатичная стабильность незаметно заменит бизнес-цель.
Устойчивые коэффициенты не превращают модель в доказательство причинного влияния рекламы. Показы и посещения могут отражать общий спрос, сезон или изменение кампаний. Для планирования это полезные признаки, а решение о сокращении рекламного бюджета требует отдельного исследования. В отчёте полезно разделить качество прогноза и интерпретацию влияния, чтобы одно не подменяло другое.
Что сохранить после эксперимента
Запишите границы трёх периодов, сетку alpha, MAE каждого варианта и итоговый результат на последнем периоде. Добавьте срезы пиковых дней: одинаковая средняя ошибка может скрывать нехватку операторов во время рекламной акции. Если ошибка растёт именно там, сравните дополнительные признаки кампании и взаимодействия вместо бесконечного уменьшения штрафа.
Что получилось в воспроизводимом расчёте
В этом примере alpha=10 даёт валидационную MAE около 3,700, а alpha=100 увеличивает её до 8,224: слишком сильный штраф уже мешает следовать за изменением нагрузки. После переобучения выбранного варианта MAE последнего периода составляет около 4,084. Разница между валидацией и финальным периодом ожидаема: это разные дни и разные наблюдения.
Чтобы проверить именно скачки коэффициентов, повторите обучение на немного сдвинутых прошлых окнах и сохраните одновременно коэффициенты и предсказания на общей контрольной группе. Сильное изменение коэффициентов при почти одинаковых ответах указывает на неоднозначность распределения влияния между близкими признаками. Если меняются и ответы, исследуйте стабильность самого решения.
При переносе alpha в другую реализацию проверьте нормировку функции потерь. Штраф к сумме квадратов и штраф к среднему квадрату требуют согласования с числом обучающих строк. Поэтому численное значение из этого примера следует переносить вместе с определением оптимизируемой функции. Сохранённая сетка эксперимента и формула позволяют воспроизвести выбор без догадок.
Следующий шаг — перенести такой эксперимент в общий конвейер, чтобы подготовка и валидация повторялись при обновлении данных. В платном курсе «ML Engineer / Data Scientist: табличные модели в продакшн» вы отработаете подготовку признаков, валидацию без утечек, сравнение моделей и сохранение inference pipeline. Откройте программу курса и переходите от отдельного расчёта к воспроизводимому обучению и batch-инференсу.
Продолжить на практике
- ML Engineer / Data Scientist: табличные модели в продакшн ↗
Практический курс для тех, кто хочет получить навыки ML Engineer / Data Scientist на реальных табличных задачах. В курсе Вы не просто обучите CatBoost/LightGBM, а соберёте полноценный production-style пайплайн: подготовка данных, feature engineering (генерация признаков), корректная валидация, защита от leakage (утечек), тюнинг через Optuna, интерпретация через SHAP, batch-инференс и REST API для предсказаний.
