# Домашнє завдання · Бустинг

> Лекція: [lecture.html](lecture.html) · Практика: [practice.ipynb](practice.ipynb) · Тест: [quiz.html](quiz.html)

Усі три рівні робляться на власних даних. Візьми будь-яку **регресійну** таблицю: ціни на
житло (`sklearn.datasets.fetch_california_housing`), споживання енергії, свій експорт із
маркетплейсу — головне, щоб цільова змінна була числом і рядків було хоча б кілька сотень.
Розбий її на навчальну, валідаційну й тестову частини **до** першого навчання й далі
не переставляй.

---

## 🟢 Рівень 1 — База

Повтори ланцюжок із лекції на своїх даних.

1. Навчи `GradientBoostingRegressor` з `n_estimators=500`, `learning_rate=0.1`, `max_depth=3`.
2. Через `staged_predict` побудуй дві криві помилки — на навчальних і на тестових даних —
   як функції кількості дерев. Вісь кількості дерев зроби логарифмічною.
3. Познач на графіку вертикальною лінією точку, де тестова помилка мінімальна.

**Зроблено, якщо:** графік побудовано, і в підписі до нього стоять три числа —
мінімальна тестова помилка, номер дерева, на якому вона досягнута, і тестова помилка
на 500-му дереві. Якщо тестова крива у тебе **не** розвертається вгору навіть на
500 деревах — напиши це прямо й поясни одним реченням, чому так могло вийти
(підказка: подивись на розмір вибірки й на рівень шуму).

---

## 🟡 Рівень 2 — Плюс

Знайди робочу пару «крок + довжина ланцюжка» чесним способом.

1. Для `learning_rate` зі списку `[0.3, 0.1, 0.05, 0.02]` навчи ланцюжок на 800 дерев.
2. Для кожного кроку знайди найкращу кількість дерев **за валідаційною вибіркою**
   (тест на цьому етапі не чіпай узагалі).
3. Побудуй таблицю: крок → кількість дерев → помилка на валідації.
4. Обери переможця й лише тоді один раз заміряй його на тесті.
5. Окремо навчи `RandomForestRegressor` зі значеннями за замовчуванням і заміряй його на
   тому самому тесті.

**Зроблено, якщо:** надруковано таблицю з чотирьох рядків, названо переможця, наведено дві
підсумкові цифри — помилка бустингу й помилка лісу на тесті, — і сформульовано одним абзацом
висновок: чи виправдав бустинг витрачений на підбір час на **твоїх** даних.

---

## 🔴 Рівень 3 — Виклик

Обери один із двох варіантів.

**Варіант А. Бустинг, стійкий до викидів.**
Реалізуй градієнтний бустинг з абсолютною втратою. Антиградієнт для неї — не залишок, а
його знак: `np.sign(y − прогноз)`. Дерева вчаться на знаках, а значення в листках підбираються
як **медіана** залишків, що потрапили в цей листок (номери листків дає `дерево.apply(X)`).
Потім зіпсуй 5% навчальних цін, помноживши їх на 10, і порівняй обидві версії.

**Зроблено, якщо:** обидві версії навчаються без помилок, і наведено таблицю з чотирьох
чисел — помилка кожної версії на чистих і на зіпсованих даних. Версія з абсолютною втратою
має просісти помітно менше; якщо цього не сталося, знайди причину й опиши її.

**Варіант Б. Скільки коштує ранній зупинці валідаційна вибірка.**
Візьми фіксований ланцюжок (`learning_rate=0.05`, `max_depth=3`, до 800 дерев) і зупиняйся
по валідації розміром 5%, 10%, 20% і 40% від навчальних даних. Для кожного розміру повтори
експеримент на **десяти** різних розбиттях і запиши середню тестову помилку та її розкид.

**Зроблено, якщо:** побудовано графік «розмір валідації → середня тестова помилка з вусами
розкиду» і сформульовано висновок: маленька валідація зупиняє в випадковому місці, велика
краде дані в навчання — де на твоїх даних оптимум.

---

## Підказки

- Якщо крива тестової помилки не має видимого дна, спробуй зменшити навчальну вибірку
  або збільшити `max_depth`: перенавчання видно тим краще, чим менше даних і чим гнучкіша
  модель.
- `staged_predict` віддає прогноз після кожного дерева й не потребує повторного навчання —
  саме тому криву на 800 дерев можна побудувати за один `fit`.
- У рівні 3А не намагайся підмінити втрату всередині `sklearn` — простіше написати власний
  цикл на `DecisionTreeRegressor`, як у практиці, і замінити в ньому два рядки.
- Порівнюючи бустинг із лісом, стеж, щоб обидва бачили **однакові** навчальні дані.
  Якщо бустинг забирає частину під валідацію, ліс має вчитися на тому самому залишку —
  інакше порівняння нечесне.
