Привет, мама.
Я теперь аналитик данных.
Один рабочий день в Orange: от первой таблицы до честного финального теста и кластеров.
🏠 + 🍊
500 РЕАЛЬНЫХ ПРОДАЖ
⬇ ДАННЫЕ ДЛЯ ПРОЕКТА
Скачайте архив до начала. В нём нет настоящих цен финальных 100 домов — сейф откроем только в конце.
⬇ Скачать данныеПривет, мама!
Помнишь, ты спрашивала, что делает аналитик данных? Сегодня мне дали историю продаж домов в Ames и сказали: «Научись оценивать цену нового дома. И пожалуйста, не обмани сам себя красивой моделью».
Я сначала обрадовался: сейчас нажму кнопку «искусственный интеллект», он всё посчитает, и можно идти пить кофе. Но оказалось, что работа аналитика начинается гораздо раньше модели — с вопроса «а что у нас вообще за данные?»
Сначала я ничего не моделировал
Мне дали 500 реальных продаж. Первым делом я спрятал 100 домов в сейф. До раздела 7 их вообще не трогаю: не смотрю цену, не считаю по ним статистику, не выбираю по ним модель. Всё до финального теста — только на 400 обучающих домах.
Мам, это как экзамен. Если заранее открыть ответы, потом уже непонятно, научился ты чему-нибудь или просто запомнил решение.
File →
01_обучение_400.csv.В Select Columns:
цена → Target, id → Meta. ID оставляем для расследования ошибок, но модель его видеть не должна.
Нет_гаража — не пустая ячейка, а настоящая категория. Это важно: «нет гаража» и «мы не знаем, есть ли гараж» — разные вещи.В основной ветке
общее_качество остаётся числом. Только для Box Plot: Edit Domain → общее_качество → categorical. Тогда уровни качества появятся как группы. После графика возвращаемся к основной числовой ветке.Мам, сначала я просто посмотрел на данные
На 400 обучающих домах средняя цена примерно $182,364, медиана — $165,800. Уже видно: дорогие дома тянут среднее вверх.
цена, Subgroup = общее_качество из отдельной categorical-ветки.Что связано с ценой?
общее_качество, Y = цена.Корреляция цены с общим качеством около 0.80, с жилой площадью — около 0.75. Это сильные связи, но не доказательство причинности.
Первая модель — специально простая
Я начинаю с Linear Regression. Не потому что она обязана победить, а потому что её легко понять и потом есть с чем сравнивать.
Рядом ставлю Constant. Для регрессии он всегда предсказывает среднее обучающей выборки. Если наша модель не лучше Constant, весь героизм можно заканчивать.
Evaluation method: Cross-validation, 5 folds.
Главная метрика нашего проекта — R². MAE и RMSE оставляем рядом, чтобы понимать ошибку в долларах.
Контрольный ориентир: Constant даёт R² около 0, Linear Regression — примерно 0.85.
Мам, два столбца могут рассказывать почти одно и то же
мест_в_гараже↔площадь_гаражаплощадь_подвала↔площадь_первого_этажажилая_площадь↔комнат_всегоВот она, мультиколлинеарность. Прогноз может быть хорошим, но коэффициенты обычной линейной регрессии становятся менее устойчивыми: похожие признаки начинают делить между собой один и тот же вклад.
В Preprocess: Normalize → center by mean, scale by SD. Выход Preprocessor подключаем прямо к Test & Score, чтобы нормализация пересчитывалась внутри каждого fold.
В Linear Regression: Ridge (L2), Alpha = 10, Fit intercept = ON.
Ориентир: R² поднимается примерно с 0.85 до 0.86.
Теперь я впервые сам придумал признаки
До этого мы принимали таблицу как есть. Теперь через Formula создаём два новых столбца:
площадь_интерьера = жилая_площадь + площадь_подвала качество_x_площадь = общее_качество * жилая_площадьПервый объединяет две площади. Второй добавляет взаимодействие: одинаковые квадратные метры у дома качества 4 и качества 9 могут стоить по-разному.
Linear: примерно 0.86.
Ridge α=10: примерно 0.87.
То есть новые признаки помогают. Небольшой прирост — тоже прирост.
А теперь Rank
Rank открываем как исследовательский инструмент: кто наверху, какие признаки выглядят сильнее. Но не нажимаем автоматически «оставить первые десять и удалить всё остальное».
Теперь нормальный турнир моделей
Условия у всех одинаковые: те же 400 домов, те же два новых признака, те же 5 folds.
| Модель | R² ↑ — результат Orange |
|---|---|
| Ridge linear regression | 0.880 |
| Linear Regression | 0.864 |
| Random Forest | 0.828 |
| AdaBoost | 0.811 |
| kNN | 0.766 |
Вот здесь я уже не спорю с данными: на нашем реальном workflow Ridge победил по R². Причём выигрыш над обычной Linear Regression небольшой — 0.880 против 0.864. Значит, регуляризация помогает, но никакого «магического разгрома» нет.
И тут я задал следующий вопрос: а как правильно готовить данные?
После этого результата я впервые почувствовал, что сама модель — только половина работы.
Мам, я уже умею сравнивать алгоритмы. Но теперь хочется понять другое: что делать с данными до модели?
• нормализовать числовые признаки;
• правильно кодировать категориальные переменные;
• понимать, когда нужен Impute и что делать с пропусками;
• не допускать leakage при preprocessing;
• отбирать признаки внутри cross-validation;
• собирать весь preprocessing в один воспроизводимый pipeline.
И вот здесь я останавливаюсь. Не потому что это неважно — наоборот. Просто preprocessing данных — отдельная большая тема следующих уроков. Сегодня достаточно понять, зачем она вообще появилась: модель уже хорошая, и следующий резерв качества лежит не только в выборе алгоритма, но и в правильной подготовке данных.
Теперь можно открыть сейф
Берём 02_финальный_тест_СЛЕПОЙ_100.csv. Цены там нет. Пропускаем его через ту же Formula и выбранную Ridge-модель, получаем прогнозы.
Только после фиксации прогнозов открываем 03_финальный_тест_ОТКРЫТЬ_В_КОНЦЕ_100.csv.
Хороший R² не означает, что модель нигде не ошибается
После Predictions сортируем по Absolute difference.
| Что нашли | Результат |
|---|---|
| Самый большой промах в final test | дом id = 186 |
| Реальная цена | $475,000 |
| Прогноз | ≈ $379,056 |
| Абсолютная ошибка | ≈ $96k |
Я не удаляю этот дом потому, что он «портит модель». Открываю строку и пытаюсь понять, чего модель не увидела.
И только теперь модели дали новый дом
Вот здесь она наконец работает, а не сдаёт экзамен. Через Create Instance задаём новый объект, затем через Formula создаём те же два признака и отправляем в Predictions.
| Признак | Значение |
|---|---|
| Общее качество | 7 |
| Жилая площадь / подвал | 1700 / 1000 |
| Гараж | 2 места, 500 |
| Полных ванных / комнат | 2 / 7 |
| Год постройки | 2000 |
| Район | CollgCr |
| Фасад / кухня / подвал | Хорошее / Хорошее / Хорошее |
А теперь я вообще убрал цену
Это уже урок 10. Берём 04_кластеризация_500_без_цены.csv и ровно восемь числовых признаков:
общее_качество, жилая_площадь, мест_в_гараже, площадь_гаража, площадь_подвала, полных_ванных, комнат_всего, год_постройки.| Кластер 1 | Кластер 2 | |
|---|---|---|
| Домов | 250 | 250 |
| Общее качество | 5.2 | 7.1 |
| Жилая площадь | 1197 | 1835 |
| Гараж, мест | 1.2 | 2.2 |
| Полных ванных | 1.1 | 2.0 |
| Год постройки | 1952 | 1991 |
Один кластер в среднем старше, компактнее и проще. Второй — новее, больше и качественнее.
Мам, вот что я на самом деле делал весь день
Сначала отделил финальный тест. Потом посмотрел данные, построил простую модель, нашёл мультиколлинеарность, попробовал Ridge, придумал два признака, проверил Rank, сравнил модели на кросс-валидации, один раз открыл финальный тест, разобрал большие ошибки и только после этого дал модели новый дом.
А в конце вообще убрал цену и посмотрел на те же дома как на задачу кластеризации.
1. Отделили 100 финальных домов и не подглядывали в них.
2. Проверили типы данных, распределения, Box Plot, Scatter Plot и корреляции.
3. Построили первую Linear Regression и сравнили её с простым простая точка отсчёта.
4. Нашли мультиколлинеарность и попробовали Ridge.
5. Создали новые признаки и посмотрели Rank.
6. Сравнили модели через 5-fold Cross-Validation.
7. В реальном Orange получили: Ridge 0.880, Linear 0.864, Random Forest 0.828, AdaBoost 0.811, kNN 0.766 по R².
8. В улучшенной Ridge-ветке получили R² = 0.914.
9. Проверили финальный test, разобрали большие ошибки и дали модели новый дом.
10. Убрали target и закончили проект кластеризацией.
Следующий вопрос студента: как правильно делать preprocessing данных? Это уже следующая большая тема.
Теперь я могу объяснить маме свою работу совсем просто: аналитик строит модели, но ещё важнее — следит, чтобы эти модели не обманули его самого.
Твой сын ❤️