1.3 Первая модель и train/test split; утечка данных и переобучение
Урок 1.3. Первая модель
После урока вы сможете:
- разделять данные на обучающую и тестовую выборки;
- строить baseline и объяснять, зачем он нужен;
- обучать линейную регрессию в pipeline и оценивать её по MAE;
- распознавать утечку данных и переобучение.
Train и test: экзамен для модели
Представьте студента, который выучил ответы на экзаменационные билеты, не понимая предмета. На знакомых билетах он получит «отлично», на новых — провалится. С моделями то же самое. Поэтому мы прячем часть данных — тестовую выборку — и проверяем модель только на ней.
from sklearn.model_selection import train_test_split
X = df[num_features + cat_features] # признаки
y = df['price_usd'] # целевая переменная
# 80% данных на обучение, 20% на проверку
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42)
random_state=42 фиксирует случайное разбиение, чтобы у вас получились те же цифры, что и в уроке.
Метрика MAE
MAE (mean absolute error) — средняя абсолютная ошибка. Если модель прогнозирует $60 000, а квартира стоит $65 000, ошибка равна $5 000. MAE — среднее таких ошибок по всем квартирам теста. Её легко объяснить руководителю: «в среднем модель ошибается на столько-то долларов».
Baseline: с чем сравниваем
Модель с MAE $6 000 — это хорошо или плохо? Без точки отсчёта ответить нельзя. Baseline — самое простое разумное решение. Для цены квартиры это правило «всегда называй медианную цену».
from sklearn.dummy import DummyRegressor
from sklearn.metrics import mean_absolute_error
baseline = DummyRegressor(strategy='median').fit(X_train, y_train)
mae_base = mean_absolute_error(y_test, baseline.predict(X_test))
print(f'Baseline MAE: ${mae_base:,.0f}') # ≈ $19 900
Линейная регрессия
Линейная регрессия ищет, на сколько долларов меняется цена при изменении каждого признака: +1 м² площади, переход из 104 серии в элитку, +1 км от центра. Подключаем её к pipeline из урока 1.2:
from sklearn.linear_model import LinearRegression
model = Pipeline([('prep', preprocess),
('lr', LinearRegression())])
model.fit(X_train, y_train)
mae_lr = mean_absolute_error(y_test, model.predict(X_test))
print(f'Linear regression MAE: ${mae_lr:,.0f}') # ≈ $5 800
print(f'Улучшение к baseline: {1 - mae_lr / mae_base:.0%}') # ≈ 71%
Результат для BishkekDom: модель ошибается в среднем примерно на $5 800 вместо $19 900 у baseline. Это на 71% точнее. Для квартиры стоимостью $65 000 ошибка около 9% — вполне рабочий ориентир для агента на первой встрече с клиентом.
Теперь модель можно применить к новой квартире:
new_flat = pd.DataFrame([{
'rooms': 2, 'area_m2': 68, 'floor': 7, 'floors_total': 12,
'year_built': 2019, 'has_parking': 1, 'distance_center_km': 3.5,
'district': 'Первомайский', 'building_series': 'Элитка',
'condition': 'Евроремонт', 'heating': 'Автономное'}])
print(f'Прогноз цены: ${model.predict(new_flat)[0]:,.0f}')
Ловушка 1: утечка данных
В выгрузке есть столбец price_per_m2 — цена за квадратный метр. Добавим его в признаки:
# MAE с price_per_m2 ≈ $2 900 — в два раза лучше!
Слишком хороший результат — повод насторожиться. price_per_m2 вычислен из цены: это цена, делённая на площадь. Модель фактически подглядывает в ответ. Агент в момент приёма объявления этого числа не знает, поэтому в реальной работе такая модель бесполезна. Это и есть утечка данных (data leakage) — одна из самых частых и дорогих ошибок в ML.
Как проверить признак на утечку: спросите себя, будет ли это значение известно в момент прогноза. Если нет или «вычислено из ответа» — признак убираем.
Ловушка 2: переобучение
Сравним ошибку на train и на test для дерева решений разной глубины (подробно деревья изучим в модуле 4):
| Глубина дерева | MAE на train | MAE на test |
|---|---|---|
| 2 | $12 200 | $13 100 |
| 5 | $7 500 | $9 000 |
| 10 | $1 700 | $8 700 |
| Без ограничения | $0 | $9 100 |
Дерево без ограничения глубины ошибается на train ровно на ноль долларов: оно запомнило каждую квартиру. Но на новых квартирах оно хуже, чем дерево глубиной 10. Это переобучение: модель выучила шум вместо закономерностей. Признак переобучения — большой разрыв между ошибкой на train и на test.
Обратите внимание: простая линейная регрессия ($5 800) обошла все деревья. Сложная модель не всегда лучше. Именно поэтому профессионалы начинают с baseline и простых моделей, а сложность добавляют только тогда, когда она даёт измеримый выигрыш.
Итоги урока и модуля
- Модель оценивается только на данных, которые она не видела (test).
- Baseline — обязательная точка отсчёта. Без него нельзя сказать, хороша ли модель.
- MAE показывает среднюю ошибку в понятных бизнесу единицах.
- Слишком хороший результат часто означает утечку данных.
- Большой разрыв между train и test означает переобучение.
Вы прошли полный цикл ML: задача → данные → очистка → pipeline → baseline → модель → проверка. Переходите к квизу и практическому заданию модуля.
