Наприкінці 1906 року статистик Френсіс Гальтон опинився на сільському ярмарку, де відвідувачі за монету вгадували вагу бика. Гальтон зібрав 787 записок і, готуючись посміятися з натовпу, порахував медіану здогадок. Вона відрізнялась від справжньої ваги менш ніж на один відсоток — точніше за будь-якого окремого фермера й точніше за експертів.
Чому так виходить? Кожен окремий учасник помиляється, але помиляється по-своєму: хтось завищує, хтось занижує. При усередненні індивідуальні відхилення гасять одне одного, а спільна для всіх крихта знання лишається. У машинному навчанні ця сама ідея називається ансамблем, а найпопулярніший ансамбль з дерев рішень — випадковим лісом.
Ми продовжимо працювати з даними попередньої лекції: 200 клієнтів банку, дві ознаки — стаж обслуговування в місяцях і середні місячні витрати, — і питання, чи залишиться клієнт на наступний рік. Там ми зупинились на неприємному висновку: одне дерево гуляє від підвибірки до підвибірки й ніколи не знає, чи можна йому вірити. Тепер полагодимо саме це.
ІдеяМудрість натовпу
Ансамбль (ensemble) — це набір моделей, чиї прогнози обʼєднують в один. Слово нічого не каже про те, які саме моделі всередині й чим вони відрізняються: ансамбль — це спосіб складати відповіді, а не окремий алгоритм навчання.
Складати можна двома способами, і різницю між ними варто закріпити відразу, бо далі вона спливе ще двічі.
- Жорстке голосування (hard voting). Кожна модель називає клас, ми рахуємо голоси, перемагає більший табір. Пʼять дерев сказали «лишиться», два — «піде»: відповідь ансамблю «лишиться», сім голосів проти двох.
- Мʼяке голосування (soft voting). Кожна модель називає не клас, а ймовірність класу, і ми беремо середнє цих ймовірностей. Ті самі сім дерев дали 0.9, 0.8, 0.7, 0.6, 0.55, 0.2, 0.1 — середнє 0.55, тобто «лишиться», але ледь-ледь.
Жорстке голосування коротше пояснювати, тому в цій лекції ми майже всюди говоритимемо
саме про нього. Але варто знати, що RandomForestClassifier у
scikit-learn насправді робить мʼяке: усереднює частки класу в листках,
куди потрапив обʼєкт. На фінальній мітці різниця зазвичай невелика, зате мʼяке голосування
дає осмислені ймовірності — а голосів «сім проти двох» на ймовірність не поділиш. Для
регресії питання не стоїть узагалі: там завжди беруть середнє прогнозів.
Щоб ансамбль виграв у окремої моделі, потрібні дві умови, і обидві однаково важливі:
- Кожна модель має бути кращою за випадкове вгадування. Ансамбль із моделей, гірших за монетку, буде ще гіршим — він упевнено помилятиметься.
- Моделі мають помилятися в різних місцях. Сто однакових копій одного дерева дадуть рівно те, що дає одне дерево: усі проголосують однаково, і жодна помилка не буде виправлена.
Друга умова — і є весь фокус. Подивімось на неї на пʼятьох деревах і одному клієнті, якого треба класифікувати. Правильна відповідь — «лишиться». Дерева дають:
| випадок | голоси пʼятьох дерев | вердикт більшості |
|---|---|---|
| дерева однакові | піде · піде · піде · піде · піде | піде — помилка |
| дерева різні | лишиться · піде · лишиться · піде · лишиться | лишиться — правильно |
У другому рядку двоє дерев із пʼятьох помилились — рівно стільки ж помилок, скільки буває в поганому дереві. Але помилки припали на різні дерева, тому в сумі їх переголосували. У першому рядку помилок теж могло бути дві на пʼять — за умови, що дерева різні. Вони не різні, тому всі пʼять помилок сіли на того самого клієнта.
Ось точне формулювання того, що ми щойно побачили: ансамбль виправляє ту помилку, яку різні моделі роблять у різних місцях, і не чіпає ту, яку всі роблять в одному й тому самому місці. Мовою попередньої теми: усереднення бʼє по дисперсії (розкид відповідей від моделі до моделі) і не бʼє по зміщенню (спільна, систематична похибка). Це один із головних висновків лекції, і ми повернемось до нього ще двічі — у розділі 07, коли вирішуватимемо не обрізати дерева, і в розділі 11, коли рахуватимемо дисперсію середнього.
Перша умова для дерев виконується легко: навіть куце дерево на реальних даних вгадує краще за монетку. Друга — головна інженерна задача всієї теми, і половина цієї лекції присвячена тому, як штучно зробити дерева різними.
ТеоріяТеорема Кондорсе
Що дає голосування більшістю, порахували ще 1785 року. Маркіз де Кондорсе розглядав
присяжних: нехай кожен із M присяжних незалежно ухвалює правильне рішення з
ймовірністю p, а вердикт визначає більшість. Ймовірність правильного вердикту
— це ймовірність, що правильно проголосувала більш ніж половина:
Словами: перебери всі варіанти, у яких правильно проголосувала більшість, порахуй ймовірність кожного — і склади їх.
M— скільки всього голосів (у нас це кількість дерев).p— ймовірність, що один голос правильний (точність одного дерева).k— скільки саме голосів вийшло правильними. Це «біжуча» величина: ми перебираємо всі можливі k.Σ(велика грецька сигма) — знак суми: «склади те, що написано праворуч, для кожного значення, зазначеного знизу». Підписk > M/2означає «для всіх k, більших за половину M», тобто саме для тих випадків, коли правих більшість.C(M, k)— кількість способів обрати k предметів із M, не зважаючи на порядок. Читається «це з M по k». Наприклад, C(3, 2) = 3: із трьох дерев рівно двоє можуть виявитись правими трьома способами — 1&2, 1&3 або 2&3.pk— ймовірність, що всі k обраних дерев угадали (ймовірності незалежних подій перемножуються), а(1 − p)M−k— що всі решта M − k помилились.
Порахуймо руками. Візьмімо три дерева з точністю 0.6 кожне. Більшість — це двоє або троє правих.
- Рівно двоє праві (k = 2). Один конкретний розклад «права пара + один хибний» має ймовірність 0.6 · 0.6 · 0.4 = 0.144. Таких розкладів C(3, 2) = 3 штуки, отже 3 · 0.144 = 0.432.
- Усі троє праві (k = 3). Один розклад, ймовірність 0.6 · 0.6 · 0.6 = 0.216.
- Складаємо: 0.432 + 0.216 = 0.648. Три дерева по 0.6 дали 0.648 — майже пʼять відсоткових пунктів задарма, без єдиної нової ознаки й без жодного гіперпараметра.
Те, що ми щойно порахували, — хвіст біноміального розподілу: сума ймовірностей «k або більше успіхів із M спроб». Висновок із формули відомий як теорема присяжних, і в ній три випадки, які треба знати напамʼять:
- Якщо
p > 0.5, то P зростає з M і прямує до одиниці. Достатньо взяти більше голосів — і колективна помилка стане як завгодно малою. - Якщо
p = 0.5, то P дорівнює 0.5 за будь-якого M. Натовп монеток — це монетка. - Якщо
p < 0.5, ефект обертається: P спадає з M і прямує до нуля. Натовп поганих моделей упевнено помиляється — і що більший натовп, то впевненіше.
Третій випадок найлегше проґавити, тому підставмо в ту саму формулу p = 0.45 —
модель, гіршу за монетку лише на пʼять сотих:
| дерев M | більшість права, точність дерева 0.45 | точність дерева 0.60 |
|---|---|---|
| 1 | 0.4500 | 0.6000 |
| 11 | 0.3669 | 0.7535 |
| 51 | 0.2359 | 0.9265 |
| 201 | 0.0774 | 0.9979 |
Двісті одне дерево, кожне з яких вгадує майже в половині випадків, разом дають
7.74% — гірше, ніж кидати монетку. Це не збій алгоритму, а та сама сума з формули:
хвіст біноміального розподілу з p нижче половини сповзає до нуля рівно так само
рішуче, як із p вище половини він піднімається до одиниці. Голосування не
створює знання — воно лише підсилює те, що вже є в кожному голосі, у який бік воно
б не показувало.
Крива Кондорсе
Скільки моделей потрібно, щоб більшість була права. Сірі криві — орієнтири для p = 0.4, 0.5, 0.6, 0.7.
Дрібний шрифтЗастереження про незалежність
У формулі Кондорсе захована умова, без якої вона не працює: голоси мають бути незалежними. Саме тому там стоїть біноміальний коефіцієнт — він рахує кількість способів отримати k правильних голосів із M, припускаючи, що кожен голос кидається окремо.
Незалежні тут означає буквально: результат одного голосу нічого не каже про
результат іншого. Якщо перший присяжний помилився, це не змінює ймовірності, що помилиться
другий. Саме на цьому припущенні тримається C(M, k) у формулі: коефіцієнт
рахує кількість способів отримати k правильних голосів із M, вважаючи, що кожен голос
кидається окремо, як окрема монетка.
У житті присяжні перемовляються, а моделі вчаться на одних і тих самих даних. Якщо всі дерева побудовані на однаковій вибірці однаковим детермінованим алгоритмом, вони будуть ідентичними. Ефективна кількість голосів у такому ансамблі дорівнює одиниці, скільки б дерев ми не додали.
Ліс не виконує обіцянки Кондорсе — і не може її виконати
Це треба сказати прямо, бо інакше два попередні розділи разом складаються в неправду. Теорема обіцяє: 201 дерево по 0.6 дає 0.998. Реальний ліс із 201 дерева на реальних даних дає, скажімо, 0.85 — і не тому, що ми щось зробили не так, а тому, що умова теореми не виконується й ніколи не виконуватиметься.
Причина проста й вимірювана. Дві бутстреп-вибірки (розділ 04) — це два жереби з того самого мішка з 200 клієнтів. Порахуймо, наскільки вони перетинаються: у середньому 63% обʼєктів однієї бутстреп-вибірки лежать і в другій (замір на наших даних, 2000 пар жеребів; те саме число 1 − 1/e, яке ми виведемо в наступному розділі). Два дерева, що вчились на майже однакових даних, і помиляються майже однаково. Незалежності немає — є лише послаблена залежність.
Тому правильне читання теореми Кондорсе таке: у формулу треба підставляти не кількість
дерев M, а ефективну кількість голосів — набагато меншу.
Скільки саме — теорема не каже, а ось наскільки дорого обходиться залежність, ми порахуємо
точно в розділі 11: там залишкова кореляція ρ перетвориться на стелю, нижче
якої дисперсію лісу не опустити жодною кількістю дерев.
І ось тут стає видно, чому трюків саме два, а не один. Бутстреп (розділ 04) міняє дані під деревом — але, як ми щойно порахували, лишає між вибірками 63% спільного, а на однакових даних жадібний алгоритм часто обирає ту саму ознаку в корінь. Знизити кореляцію ще нижче можна тільки втрутившись у сам алгоритм: заборонити деревам дивитись на всі ознаки одразу. Це другий трюк — випадкові підмножини ознак, розділ 06. Один трюк без другого дає ансамбль, який працює, але недопрацьовує.
Трюк першийБеггінг і бутстреп
Ідеально було б навчити кожне дерево на власній свіжій вибірці з реального світу: сто дерев — сто незалежних наборів по 200 клієнтів. Тоді дерева були б справді незалежними, і теорема Кондорсе працювала б дослівно. Але свіжі дані коштують грошей і часу, а вибірка в нас одна.
Лео Брейман 1996 року запропонував підробку, яка виявилась напрочуд робочою: бутстреп (bootstrap) — витягування n обʼєктів із наявних n з поверненням. Ідея не його: сам прийом придумав статистик Бредлі Ефрон 1979 року як спосіб оцінити похибку будь-якої статистики, коли повторити експеримент неможливо. Брейман приніс цей прийом у машинне навчання.
Мішок із поверненням — на пʼятьох клієнтах
Уяви мішок із пʼятьма картками: А Б В Г Д. Тягнемо картку, записуємо ім'я, кладемо картку назад і перемішуємо. І так пʼять разів — рівно стільки, скільки карток у мішку. Ось один такий жереб:
| витягування | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| випало | Б | Г | Б | Д | Г |
Нова вибірка — це Б Б Г Г Д: пʼять записів, як і було. Але Б і Г потрапили двічі, а А і В не потрапили взагалі. Дерево, навчене на цій вибірці, про клієнтів А і В нічого не знатиме, зате Б і Г вважатиме вдвічі важливішими, ніж вони є. Наступний жереб дасть інший перекіс — і інше дерево.
Чому саме з поверненням? Питання не риторичне, і відповідей три.
- Без повернення нічого не вийде взагалі. Витягнути n обʼєктів із n без повернення — це просто взяти всю вибірку, перемішавши порядок. Ті самі 200 клієнтів, те саме дерево. Жодної різноманітності.
- Розмір лишається n. Можна було б брати підвибірки меншого розміру без повернення — такий варіант існує й зветься pasting. Але тоді кожне дерево вчиться на меншій вибірці, ніж могло б, і стає слабшим. Повернення дає різноманітність, не забираючи обсягу.
- Повторення — це і є перекіс. Різні дерева бачать не просто різні набори клієнтів, а різні ваги тих самих клієнтів. Саме цей перекіс і зсуває пороги розрізів, роблячи дерева несхожими.
Ціна цього трюку теж є, і про неї треба сказати відразу: частина обʼєктів у кожен жереб не потрапляє. Скільки саме — рахуємо в наступному розділі, і виявиться, що ця «втрата» обернеться найкориснішим побічним ефектом усієї теми.
Беггінг — це бутстреп плюс усереднення
Метод «навчи модель на кожній бутстреп-вибірці й усередни прогнози» називається
беггінгом. Назва — склеєне bootstrap aggregating: перше слово
про те, звідки беруться вибірки, друге (aggregating — «зведення докупи») про те, що робиться
з прогнозами. Алгоритм цілком уміщується в три рядки:
- Зроби T бутстреп-вибірок розміру n.
- Навчи на кожній свою копію моделі — незалежно від інших.
- Для прогнозу спитай усі T копій і візьми більшість (класифікація) або середнє (регресія).
Зверни увагу, чого в цьому описі немає: слова «дерево». Беггінг — обгортка над
будь-якою моделлю, і в scikit-learn це окремий клас
BaggingClassifier(estimator=…), куди можна покласти хоч дерево, хоч kNN, хоч
логістичну регресію.
Випадковий ліс = беггінг над деревами плюс другий трюк із розділу 06. Якщо другий
трюк вимкнути (дозволити вузлу дивитись на всі ознаки), лишиться чистий беггінг — рядок
mtry = p у таблиці розділу 06 саме про це.
АрифметикаЗвідки береться 63%
Скільки різних обʼєктів потрапляє в одну бутстреп-вибірку? Порахуймо це до кінця — виведення коротке й дуже показове.
Візьмімо конкретного клієнта. За одне витягування ймовірність, що дістали саме його, дорівнює 1/n. Отже, ймовірність, що дістали не його:
Витягування незалежні, тому ймовірність, що його не взяли жодного разу за n спроб, — це добуток n однакових множників:
Тепер найцікавіше. Вираз (1 − 1/n)n має дві
частини, які тягнуть у різні боки: множник 1 − 1/n із ростом n
наближається до одиниці (одиниця в будь-якому степені — одиниця), а степінь
n росте (число, менше за одиницю, у великому степені прямує до нуля). Хто
переможе — з формули не видно. Тому просто підставмо числа й подивімось:
| n | (1 − 1/n)n | як це рахується |
|---|---|---|
| 2 | 0.25000 | 0.5 · 0.5 |
| 5 | 0.32768 | 0.8 помножене саме на себе 5 разів |
| 10 | 0.34868 | 0.9 у степені 10 |
| 20 | 0.35849 | 0.95 у степені 20 |
| 100 | 0.36603 | 0.99 у степені 100 |
| 1000 | 0.36770 | 0.999 у степені 1000 |
Стовпчик не розбігається й не спадає до нуля — він упирається в число 0.3678… Ніяка з двох частин не перемогла, вони врівноважились. Математики записують цей факт так:
Причому збіжність швидка: вже при n = 20 значення дорівнює 0.358, при n = 100 — 0.366.
Отже, приблизно 36.8% обʼєктів у кожну конкретну вибірку не потрапляють, а 63.2% потрапляють хоча б раз:
lim і що таке e — якщо ці значки
бачиш уперше.
limn→∞читається «границя при n, що прямує до нескінченності», і означає рівно те, що ми щойно побачили в таблиці: до якого числа підходить вираз, коли n роблять дедалі більшим. Не «чому дорівнює при нескінченності» — нескінченність не число, підставити її нікуди. Саме «до чого підходить». Ніякої вищої математики тут не потрібно: таблиця в кроці 3 і є доказ, який можна перевірити калькулятором.e≈ 2.71828 — така сама іменована стала, як π ≈ 3.14159. Її не обирали для краси: вона вилазить сама, щоразу, коли щось множиться саме на себе багато разів маленькими кроками — складні відсотки, радіоактивний розпад, і ось наш мішок із картками.e−1— це просто 1/e ≈ 0.36788.- Тому 36.8% і 63.2% у цій темі — не підібрані числа й не властивість наших даних. Це те саме 1/e, що й у складних відсотках, і воно було б там само, якби ми міряли не клієнтів банку, а листівки в поштовій скриньці.
Два наслідки. Перший: кожне дерево бачить приблизно дві третини даних, тобто вчиться на трохи іншій задачі — саме те, що нам потрібно для різноманітності. Другий, і він виявиться подарунком: третина даних для кожного дерева лишається невикористаною. На них це дерево можна чесно перевірити, нічого не відкладаючи заздалегідь.
Що відбувається при бутстрепі
Кожна клітинка — один обʼєкт вибірки. Колір показує, скільки разів його витягнули.
Трюк другийВипадкові ознаки й декореляція
Самого беггінгу мало. Якщо в даних є одна дуже сильна ознака, то майже кожна бутстреп-вибірка обере її для кореня — і дерева знову вийдуть схожими, просто з трохи різними порогами. Кореляція між ними лишиться високою, а ансамбль виграє менше, ніж міг би.
Друга ідея Бреймана усуває саме це: у кожному вузлі розріз шукається не серед
усіх ознак, а серед випадкової підмножини розміру mtry. Не один раз на
дерево — а заново в кожному вузлі. Якщо сильна ознака цього разу не потрапила у вибір, дерево
змушене будувати розріз на чомусь іншому й знаходить структуру, яку інакше б проґавило.
mtry прийшло
з реалізації випадкового лісу мовою R і стало загальновживаним у статтях — саме тому ми
користуємось ним у тексті. Але в scikit-learn цей самий параметр зветься
max_features, і шукати mtry в документації Python марно. Значення
за замовчуванням для класифікації — рядок max_features="sqrt", тобто корінь
квадратний із кількості ознак, округлений угору; для регресії
RandomForestRegressor за замовчуванням бере 1.0, тобто всі ознаки.
Число, частку або рядок "log2" можна задати вручну.Стандартні рекомендації такі:
| задача | mtry за замовчуванням | міркування |
|---|---|---|
| класифікація | √p | сильна декореляція, дерева слабші, але різні |
| регресія | p/3 | у регресії дерева чутливіші, потрібно більше ознак |
| mtry = p | це вже просто беггінг | дерева найсильніші, але найсхожіші |
Тут працює компроміс сили й кореляції, який Брейман сформулював прямо: якість лісу зростає, коли окремі дерева сильніші, і коли вони менш корельовані. Але ці дві вимоги тягнуть у різні боки. Малий mtry робить дерева різними — і водночас слабшими, бо найкорисніша ознака часто буває недоступною. Великий mtry робить кожне дерево сильним — і всі їх схожими. Оптимум зазвичай десь посередині, і √p — непогане перше наближення.
Щоб побачити компроміс на числах, потрібно більше ознак, ніж дві. Для наступного інтерактиву в датасет додано ще чотири колонки: кількість транзакцій (майже дублює витрати), вік акаунта в застосунку (майже дублює стаж), ідентифікатор сесії (чистий шум) і канал звернення (теж шум, але лише двох значень).
Скільки ознак дозволити вузлу
Шість ознак, ліс із 24 дерев. Три криві: сила окремого дерева, схожість дерев і точність ансамблю.
ЗбіркаАлгоритм цілком
Тепер можна записати весь випадковий ліс у пʼять рядків. Нехай задано кількість дерев
T, розмір підмножини ознак mtry й обмеження на дерево:
- Для кожного дерева
t = 1…Tвитягни бутстреп-вибірку розміру n з поверненням. - Вирости на ній дерево звичайним жадібним алгоритмом, але в кожному вузлі перебирай
лише
mtryвипадково обраних ознак. - Дерево не обрізай. Так, у попередній лекції ми казали, що глибокі дерева перенавчаються — тут це навмисне.
- Для прогнозу пропусти обʼєкт крізь усі T дерев і візьми більшість голосів (або середнє від часток класу, якщо потрібні ймовірності).
- Обʼєкти, що не потрапили в бутстреп конкретного дерева, використай для OOB-оцінки.
Пункт 3 бентежить найбільше, тому розберімо його окремо. Глибоке дерево має мале зміщення й велику дисперсію. Усереднення багатьох моделей зменшує дисперсію, але не змінює зміщення. Отже, вигідно брати в ансамбль моделі саме з малим зміщенням — а з дисперсією розбереться усереднення. Обрізане дерево мало б і зміщення, і від нього ансамбль уже не врятує.
Скільки дерев треба
Повертаємось до двох ознак. Насиченість кольору — наскільки одностайно голосує ліс у цій точці.
n_estimators обирають не якістю, а бюджетом часу: 100–500 у
типовій задачі, більше — коли потрібні стабільні оцінки ймовірностей.ПеревіркаДерево проти лісу
Найпереконливіший доказ — прямий експеримент. Візьмімо ту саму процедуру, що в кінці попередньої лекції: витягуємо нову підвибірку клієнтів і вчимося з нуля. Тільки тепер паралельно навчаються двоє: одне дерево і ліс із 25 дерев.
Натисни кнопку кілька разів і дивись на числа праворуч. Нас цікавить не так точність, як стабільність: наскільки сильно змінюється відповідь моделі, коли дані змінились ледь-ледь.
Міряти стабільність будемо величиною, яку назвемо зсувом межі. Модель ділить площину «стаж × витрати» на області: тут кажемо «лишиться», тут «піде». Після перенавчання на новій підвибірці поділ виходить іншим. Зсув межі — це частка площини, де новий поділ не збігся зі старим. Нуль означає «модель відтворилась точно», 20% — «пʼята частина всіх можливих клієнтів дістала протилежний вердикт лише тому, що ми перетасували навчальні дані».
Саме це число, а не точність, і є предметом розділу. Ось чому.
- Точність одного запуску нічого не доводить. Тисни кнопку далі — рано чи пізно трапиться запуск, де дерево виявиться точнішим за ліс. Це не спростування: одне вимірювання нестабільної моделі — це вимірювання її везіння. Ліс виграє у середньому за всі запуски, і саме тому в табло є окремий рядок із середнім.
- Нестабільність дорого коштує поза точністю. Модель, яка після щотижневого перенавчання переклеює 15% площини, щотижня міняє рішення про тих самих клієнтів, хоча ті не змінились. Пояснити таке рішення неможливо, оскаржити — теж.
- Зсув межі — це дисперсія, яку видно оком. Дисперсія з формул попередньої теми тут перестає бути абстракцією: це буквально мерехтіння картинки між натисканнями кнопки.
Наскільки ліс стабільніший
Ліворуч — одне дерево, праворуч — ліс із 25 дерев. Обидва вчаться на одній і тій самій новій підвибірці.
БонусOOB — безкоштовна валідація
Повернімось до тих 36.8%, що лишились поза кожною бутстреп-вибіркою. Для конкретного клієнта приблизно третина дерев його не бачила під час навчання. Зберімо голоси тільки цих дерев — вийде чесний прогноз для клієнта, зроблений моделлю, яка з ним не знайома.
Повторивши це для всіх n клієнтів, отримаємо out-of-bag оцінку якості:
n — скільки всього клієнтів;
i — номер клієнта, і Σi означає «пройди
по всіх клієнтах і склади». yi — справжня відповідь
для клієнта i, ŷi (читається «ігрек з дашком») —
прогноз; надпис OOB нагадує, що прогноз зроблено лише тими деревами, які цього
клієнта не бачили. Квадратні дужки [ … ] — не множення й не масив, а
скорочення для «1, якщо написане всередині правда, і 0, якщо неправда». Отже вся формула
словами: порахуй, скільки клієнтів вгадано, і поділи на кількість клієнтів. Це
звичайна частка правильних відповідей — просто записана так, щоб було видно, які саме
відповіді беруться.Це майже те саме, що крос-валідація, тільки безкоштовно: ніякого повторного навчання,
ніякої відкладеної вибірки. У scikit-learn вона вмикається одним аргументом
oob_score=True, і результат читається з rf.oob_score_.
Чому це справді безкоштовно
Порівняймо витрати. Щоб отримати чесну оцінку відкладеною вибіркою, треба забрати з навчання, скажімо, 20% даних — модель вчиться на 160 клієнтах замість 200 і виходить гіршою. Пʼятикратна крос-валідація повертає ці дані, але коштує пʼять повних навчань замість одного. OOB не забирає жодного обʼєкта й не додає жодного навчання: розподіл на «бачив» і «не бачив» уже відбувся сам, усередині бутстрепу, і залишилось тільки не викинути прапорці, які й так лежать у памʼяті. Це рідкісний випадок, коли безкоштовність не має підступу — але має межі.
Коли OOB не можна вірити
- Дерев мало. Про кожного клієнта голосує лише та третина дерев, яка його не бачила. У нашому лісі з 36 дерев це в середньому 13.1 дерева на клієнта — подивись на табло «дерев на голос» в інтерактиві нижче. При десятьох деревах на голос припадає близько трьох, і OOB оцінює вже не той ансамбль, який ти збираєшся використовувати. Нижче сотні дерев до OOB варто ставитись як до орієнтира.
- OOB систематично трохи занижує. Причина — та сама третина: ансамбль із 13 дерев гірший за ансамбль із 36, а міряємо ми саме менший. Тому очікуваний напрямок похибки — песимістичний, і це найкращий із можливих напрямків: краще недооцінити модель, ніж переоцінити.
- Але власний шум OOB зазвичай більший за це заниження. Наша OOB рахується на 200 обʼєктах, а частка на 200 обʼєктах має стандартну похибку близько ±0.03, тобто ±3 в. п. Це помітно більше за систематичний перекіс, тому знак різниці може вийти будь-який: в інтерактиві нижче при 36 деревах OOB дає 87.5% проти 85.3% на тесті — вийшла вища, попри теоретичний песимізм. Висновок практичний: різниці в 2-3 в. п. між OOB і тестом ні про що не свідчать, і шукати в них сенс не треба.
- Без бутстрепу OOB не існує. Якщо поставити
bootstrap=False, кожне дерево бачить усі дані, обʼєктів «поза мішком» немає взагалі, іoob_score=Trueпросто впаде помилкою.
OOB проти тестової вибірки
Рожева крива рахується всередині навчальних даних, бірюзова — на 1200 клієнтах, яких модель не бачила.
ІнтерпретаціяВажливість ознак і її пастки
Ліс втратив головну перевагу дерева: сто дерев не намалюєш і вголос не прочитаєш. Натомість він пропонує зведену характеристику — важливість ознак. Способів порахувати її два, і вони міряють різні речі.
MDI — середнє зменшення забрудненості
Це те, що sklearn віддає у feature_importances_. Для кожного
вузла беруть приріст чистоти від його розрізу, множать на частку обʼєктів у вузлі й додають
до рахунку тієї ознаки, за якою різали. Потім усе усереднюють по деревах і нормують на суму:
Словами: пройди по всіх вузлах усіх дерев, де різали за ознакою f, і склади їхні прирости чистоти — кожен зважений тим, скільки обʼєктів через цей вузол пройшло.
f — ознака, важливість якої
рахуємо. Σвузли по f — сума по всіх вузлах, де розріз
зроблено саме за цією ознакою. nвузла — скільки
обʼєктів дійшло до цього вузла, N — скільки всього обʼєктів у навчальній
вибірці; їхнє відношення — вага вузла. Вона потрібна, щоб корінь, крізь який проходять усі
200 клієнтів, важив більше за листковий вузол із трьома обʼєктами.
Δimpurity (грецька дельта — «зміна») — наскільки
зменшилась забрудненість Джині після цього розрізу; це та сама величина, яку жадібний
алгоритм із теми 23 · Дерева рішень максимізує, обираючи розріз. Наприкінці всі шість чисел ділять на їхню
суму, щоб вони складались в одиницю — тому MDI читається як частка, а не як
абсолютна величина.Рахується безкоштовно — усі числа вже є після навчання. Але має дві відомі вади. Перша: зсув на користь ознак із багатьма різними значеннями. У неперервної ознаки сотні кандидатів на поріг, у бінарної — один; за чистої випадковості неперервна частіше знаходить розріз, який хоч трохи зменшує забрудненість. Друга: MDI рахується на навчальних даних, тому щедро оплачує розрізи, зроблені по шуму.
Перестановкова важливість — падіння якості від псування ознаки
Перестановкова важливість (permutation importance) — так вона зветься в глосарії курсу; у коді ти зустрінеш її під англійською назвою, як функцію permutation_importance з модуля sklearn.inspection, і далі в лекції ми теж користуємось коротким «PI». Підхід прямолінійний: візьми навчений ліс і тестову вибірку, виміряй точність.
Потім перемішай значення однієї ознаки між обʼєктами — так її звʼязок із
цільовою змінною руйнується, а розподіл лишається тим самим — і виміряй точність знову.
Наскільки вона впала, настільки ознака й важлива.
Дорожче (потрібні повторні прогони) і шумніше (перемішування випадкове, тому роблять кілька повторів і усереднюють), зате чесно: вимірюється на даних, яких модель не бачила.
Дві важливості на одному лісі
Той самий ліс, шість ознак. Дві останні — навмисний шум, який нічого не пояснює.
Випишімо те, що показує ця фігура, числами — бо в них увесь сенс розділу. Ліс із 30 дерев, шість ознак, mtry = 3, базова точність 82.8% на 500 тестових клієнтах:
| ознака | MDI, частка | PI, падіння точності | що це насправді |
|---|---|---|---|
| стаж | 21.2% | 10.4 в.п. | справжня ознака |
| витрати | 26.2% | 10.4 в.п. | справжня ознака |
| транзакції | 29.6% | 13.4 в.п. | майже дублікат витрат |
| у застосунку | 16.0% | 0.6 в.п. | майже дублікат стажу |
| id сесії | 6.1% | −0.2 в.п. | чистий шум |
| канал | 0.9% | 0.0 в.п. | чистий шум, два значення |
Два останні рядки — та сама пастка, показана в лоб. Обидві ознаки шумові за побудовою, обидві мали б отримати нуль. Але «id сесії» — випадкове дійсне число, у якого 200 різних значень і, отже, 199 кандидатів на поріг; «канал» приймає лише два значення, тобто дає рівно один можливий поріг. Вибір із двохсот дає більше шансів випадково натрапити на розріз, який хоч трохи зменшує забрудненість — і MDI віддає шуму з багатьма значеннями 6.1% проти 0.9% у шуму з двома. Вся різниця між ними — у кількості значень, бо інформації нема ні там, ні там. Permutation importance ставить обох на місце: −0.2 і 0.0 відсоткових пункти, тобто нуль у межах похибки перемішування.
Значення нижче нуля не має бентежити: якщо ознака нічого не важить, зіпсувати її іноді означає випадково покращити результат. Саме тому перемішування повторюють кілька разів і усереднюють — покрути повзунок повторів і подивись, як число заспокоюється.
А рядок «у застосунку» показує другу пастку, ще до того, як ми до неї дійшли: MDI дає йому 16.0%, permutation importance — 0.6 в.п. Ознака справжня, але вона майже повторює «стаж», і викинути її можна майже безкарно — бо все, що вона знає, уже є в іншій колонці.
Обидві важливості відповідають на питання «що впливає загалом». Питання «чому модель так вирішила про це конкретне оголошення» — інше, і відповідають на нього іншими засобами: значеннями Шеплі, локальними наближеннями, частинною залежністю. Разом із тим, чому переконливе пояснення буває небезпечнішим за його відсутність, це розібрано в темі 40 · Інтерпретованість.
Це легко перевірити на тих самих даних. Приберімо обидва майже-дублікати — «транзакції» й «у застосунку» — і навчімо ліс наново: ті самі 30 дерев, те саме зерно, чотири ознаки замість шести й mtry = 2 (та сама половина ознак на вузол, що й раніше).
| ознака | MDI · шість ознак | MDI · чотири ознаки |
|---|---|---|
| витрати | 0.262 | 0.494 |
| стаж | 0.212 | 0.351 |
| id сесії | 0.061 | 0.144 |
| канал | 0.009 | 0.012 |
Важливість «витрат» піднялась із 0.262 до 0.494, «стажу» — з 0.212 до 0.351, і сталося це без жодної зміни в самих ознаках: витрати лишились тими самими витратами. Змінилось тільки те, що їм більше ні з ким ділити заслугу. Точність лісу при цьому майже не ворухнулась — 84.2% проти 84.4% на тестовій вибірці, тобто дві викинуті колонки не несли нічого, чого не було в решті.
Звідси головний практичний висновок розділу: важливість ознаки — це не її цінність, а її частка в конкретній моделі на конкретному наборі колонок. Додай дублікат — і важливість впаде вдвічі, хоча ознака та сама. Прибери дублікат — і зросте вдвічі. Приймати рішення «викинути ознаку, бо в неї мала важливість» без огляду на те, з ким вона корелює, — прямий шлях викинути потрібне.
ТеоріяЧому ліс не перенавчається
Тепер найцікавіше питання лекції: чому ансамбль із необрізаних дерев, кожне з яких перенавчене, не перенавчений сам? Відповідь дає розклад дисперсії середнього.
Нехай кожне дерево дає прогноз із дисперсією σ². Якщо прогнози незалежні, дисперсія середнього з M штук — класична формула:
Тобто при M = 100 розкид падає в сто разів. Занадто добре, щоб бути правдою.
Насправді дерева вчаться на тих самих даних, і їхні помилки корельовані з коефіцієнтом ρ. Тоді формула стає такою:
Перевірмо її на краях, це найшвидший спосіб повірити формулі. При ρ = 0
(дерева незалежні) перший доданок зникає, і лишається σ²/M — рівно крок 1.
При ρ = 1 (усі дерева ідентичні) другий доданок зникає, і лишається
σ² — дисперсія одного дерева, тобто ансамбль не дав нічого. Обидва краї
сходяться зі здоровим глуздом.
Другий доданок згасає з ростом M — його ми перемагаємо кількістю дерев. Перший
не залежить від M взагалі: скільки дерев не додавай, нижче
ρσ² дисперсія не опуститься. Ось чому декореляція така важлива: вона
знижує саме ту стелю, яку кількістю не пробити.
Var— дисперсія, міра розкиду. Тут вона міряє не помилку, а хиткість: наскільки прогноз для одного й того самого клієнта стрибає, якщо перенавчити модель на іншій підвибірці. Це те саме, що ми бачили оком у розділі 08 як «зсув межі».σ²(мала грецька сигма у квадраті) — дисперсія прогнозу одного дерева. Що вона більша, то дужче окреме дерево гуляє.M— кількість дерев.ρ(мала грецька ро) — коефіцієнт кореляції між прогнозами двох дерев: 0 означає «зовсім не повʼязані», 1 — «завжди однакові». Це і є та сама залежність, про яку йшлося в розділі 03, тільки тепер із числом.
Порахуймо руками. Візьмімо σ² = 1 (щоб
дивитись на частки) і подивімось, що дає кількість дерев при різній кореляції:
| M | ρ = 0 (мрія) | ρ = 0.1 (сильна декореляція) | ρ = 0.4 (типовий ліс) | ρ = 0.9 (дерева-близнюки) |
|---|---|---|---|---|
| 1 | 1.000 | 1.000 | 1.000 | 1.000 |
| 10 | 0.100 | 0.190 | 0.460 | 0.910 |
| 100 | 0.010 | 0.109 | 0.406 | 0.901 |
| 10 000 | 0.0001 | 0.1001 | 0.4001 | 0.9001 |
| стеля | 0 | 0.1 | 0.4 | 0.9 |
Перевірмо один рядок вручну, щоб не було магії: ρ = 0.4, M = 10
дає 0.4 · 1 + (1 − 0.4) · 1 / 10 = 0.4 + 0.06 = 0.46. Тепер прочитаймо таблицю
цілком. Перехід від 10 до 100 дерев при ρ = 0.4 знижує розкид із 0.460 до 0.406 — виграш
є, але скромний. Перехід від 100 до 10 000 дерев (у сто разів більше обчислень!) дає
0.406 → 0.4001, тобто майже нічого. А ось перехід від ρ = 0.4 до ρ = 0.1 при тих самих
100 деревах — це 0.406 → 0.109, розкид учетверо менший. Кореляція важить незмірно
більше за кількість, і саме тому лекція витратила два розділи на два трюки
декореляції й один абзац на вибір n_estimators.
Стеля, яку не пробити кількістю
Дисперсія середнього за формулою кроку 2 при σ² = 1. Пунктир — стеля ρσ².
n_estimators: після кількох десятків дерев це вже треті знаки після коми.І тепер стає видно, як ліс усе-таки може перенавчитись, попри назву розділу. Формула нічого не обіцяє про зміщення — вона лише прибирає дисперсію. Якщо дерева вивчили шум однаково (наприклад, вибірка крихітна, і всі бутстреп-жереби майже збігаються; або в даних є ознака-витік, за яку хапається кожне дерево), то помилка перестала бути дисперсією й стала зміщенням — а зміщення усередненням не лікується. Формально це видно як ρ, що поповзла до одиниці: стеля піднялась до σ², і кількість дерев уже нічого не варта.
Тепер видно, як усе складається докупи. Бутстреп і випадкові ознаки зменшують ρ. Велике M прибирає другий доданок. Необрізані дерева тримають зміщення малим. Ліс справді може перенавчитись — але тільки якщо ρ близька до одиниці, тобто якщо дерева перестали бути різними.
ПорівнянняЛіс проти бустингу
Випадковий ліс — не єдиний спосіб зібрати ансамбль із дерев. Другий великий підхід — бустинг (XGBoost, LightGBM, CatBoost), і різниця між ними принципова. Тут — коротке порівняння; механіку бустингу крок за кроком розібрано в наступній темі 25 · Бустинг.
Ліс будує дерева паралельно й незалежно, кожне на своїй вибірці, і зменшує дисперсію. Бустинг будує дерева послідовно: кожне наступне вчиться виправляти помилки вже зібраного ансамблю, і зменшує зміщення. Звідси всі практичні відмінності:
| критерій | випадковий ліс | градієнтний бустинг |
|---|---|---|
| дерева | глибокі, незалежні | мілкі (3–8), послідовні |
| зменшує | дисперсію | зміщення |
| навчання | паралельне, легко масштабується | послідовне за побудовою |
| налаштування | працює «з коробки» | чутливий до learning_rate і глибини |
| перенавчання | не росте з кількістю дерев | росте — потрібна рання зупинка |
| стеля якості | трохи нижча | зазвичай вища на табличних даних |
Практичне правило просте. Ліс — це надійна базова лінія, яку варто отримати за пʼять хвилин на початку роботи: він майже не вимагає налаштування, дає OOB-оцінку задарма й рідко поводиться несподівано. Бустинг — це те, чим виграють змагання, коли готовий витратити час на підбір гіперпараметрів і маєш достатньо даних.
ПідсумокЩо варто винести
Випадковий ліс — це відповідь на конкретну ваду конкретної моделі. Дерево має малу похибку зміщення й величезну дисперсію; усереднення багатьох дерев прибирає дисперсію, не чіпаючи зміщення. Уся інженерія зводиться до того, щоб дерева не були схожими:
- Бутстреп дає кожному дереву свої дві третини даних;
- випадкові ознаки в кожному вузлі не дають одній сильній ознаці захопити всі корені;
- голосування більшістю перетворює купу різних помилок на одну маленьку — за умовою теореми Кондорсе;
- OOB дає чесну оцінку якості без окремої валідаційної вибірки;
- важливість ознак частково повертає інтерпретованість — але permutation importance надійніша за MDI.
І головне, що варто запамʼятати з обох лекцій: слабкість алгоритму не завжди лікують всередині алгоритму. Іноді дешевше побудувати сто його недосконалих копій і дати їм проголосувати.