У темі 08 ми розібрали дошку оголошень про вживані телефони й знайшли там усе, що зазвичай знаходять: пропуски, дублікати, памʼять, записану текстом, і стовпець, яким користуватись не можна. Таблиця стала чистою. І тут виявляється незручне: чиста таблиця сама по собі майже нічого не знає про шахрайство.
Порахуємо. Кореляція кожного вихідного стовпця з таргетом на 1 100 оголошеннях, у яких ціна відома:
Найсильніший звʼязок — 0.116, і той у віку акаунта. Ціна, головне поле оголошення, дає рівно нуль. Але ж ми знаємо, що шахрай видає себе саме ціною: він ставить неймовірну знижку або, навпаки, захмарну суму під велику передоплату. Знання є, а в числах його немає.
Причина проста, і вона не в даних. Модель бачить рівно те, що ти їй поклав, і не здогадається ні про що. Стовпець «ціна» містить число 1 310 — і воно справді нічого не означає, поки не сказано, скільки коштує такий самий телефон. Вся ця тема — про те, як дописати в таблицю стовпці, у яких твоє розуміння задачі нарешті стає числом. Це й називається інженерія ознак (feature engineering).
groupby,
transform, merge, робота з датами — ми розібрали в
темі 39 курсу Python, а самі дати —
у темі 24 того ж курсу. Тут ми не
пояснюємо, як викликати метод: ми говоримо про те, який стовпець варто
ним зробити.ПерекладОзнака як переклад
Уяви, що ти показуєш оголошення знайомому, який продає телефони десять років. Він дивиться дві секунди: «Beta 12 двадцять другого року за 1 310 — так не буває». Він не рахував кореляцій, він порівняв ціну з тим, що знає про цю модель.
Модель такого знання не має: слово «Beta 12» для неї — просто одна з шести категорій. Тому фразу «так не буває» треба перекласти в число: поділити ціну оголошення на типову ціну для цієї моделі й року. Для нашого оголошення це 1 310 ÷ 6 740 = 0.19. Ось тепер у таблиці є те, що знайомий побачив очима.
Звідси головна думка теми, і вона майже банальна: інженерія ознак — це переклад людського розуміння задачі на мову чисел. Ознака, про яку ми домовились ще в темі 02, не обовʼязково має бути стовпцем із файлу — її можна й треба зробити. Не пошук магічної формули, а послідовна відповідь на питання «що саме я бачу в цих даних такого, чого не видно в окремому стовпці».
Але спершу треба домовитись, як ми відрізнятимемо вдалий переклад від невдалого.
Три лінійки замість моделі
Кореляція (у нас — Пірсона) відповідає на питання «чи ростуть ці два числа разом». Ми користувались нею в темі 08. Її межа названа прямо в означенні: вона бачить лише монотонний звʼязок. Якщо шахрайськими є і дуже дешеві, і дуже дорогі оголошення, вона покаже нуль.
Розділюваність класів — наскільки розходяться розподіли ознаки в чесних і шахрайських оголошеннях. Зручна міра для цього в нас уже є: площа під ROC-кривою з теми 06. Візьмемо саму ознаку як оцінку ризику й порахуємо AUC: 0.5 — розподіли збігаються повністю, 1.0 — не перетинаються зовсім. Сліпа пляма та сама, що в кореляції: AUC рахує лише порядок.
Взаємна інформація (mutual information, MI) — це відповідь на питання
«наскільки менше невизначеності в таргеті лишається, якщо я знаю значення ознаки».
Вважай її кореляцією, яка бачить і нелінійне. Нуль означає «ознака й таргет незалежні»;
верхньої межі немає — числа порівнюють між собою, а не з одиницею. У
scikit-learn це mutual_info_classif.
ВідношенняВідношення й різниці
Найпростіший прийом і найчастіше найсильніший: поділити одне число на інше. Сира величина майже завжди безглузда без масштабу: ціна без типової ціни, зарплата без медіани по місту, пальне без пробігу.
На нашій дошці напрошуються чотири переклади:
- ціна ÷ типова ціна для цієї моделі й року — «наскільки це дешевше або дорожче за нормальне»;
- ціна ÷ памʼять — ціна за гігабайт;
- вік телефона = поточний рік − рік випуску — різниця, а не відношення, але той самий прийом;
- ціна − медіана по моделі й року — та сама думка, але через віднімання.
«Типової ціни» в таблиці немає — її треба порахувати з даних: медіана ціни всередині групи «модель + рік». Для Beta 12 двадцять другого року таких оголошень 17, їхня медіана — 6 740 грн. Тепер увімкни всі чотири переклади по черзі.
Конструктор ознаки
Угорі — розподіл нової ознаки окремо для чесних і шахрайських оголошень. Унизу для порівняння — той самий розподіл для вихідної ціни. 1 100 оголошень, у яких ціна відома.
mutual_info_classif.Натисни «ціна ÷ типова» й подивись на кореляцію: +0.018. Нуль. Ознака, яку ми щойно назвали головною думкою теми, за кореляцією не варта нічого.
А тепер подивись на гістограму. Рожеві оголошення зібрались у два акуратні горби: один біля 0.3, другий біля 3 — шахрай ставить або занижену ціну, або завищену. Взаємна інформація це бачить: 0.336 проти 0.069 у сирої ціни. Кореляція не бачить, бо два горби по різні боки одиниці в сумі дають нахил нуль.
Це не вада ознаки, а вада лінійки. І виправляється це ще одним перекладом: якщо нам важлива не сторона, а відстань від норми, візьмемо модуль логарифма відношення.
Логарифм тут потрібен, щоб «удвічі дешевше» й «удвічі дорожче» дали однакову величину: ln(0.5) = −0.69, ln(2) = +0.69. Без нього дешева приманка виглядала б меншим відхиленням, ніж дорога. Модуль складає два горби в один. Натисни «відхилення»: кореляція +0.774, AUC 0.990.
Не чекай таких чисел на живих даних. Наша дошка синтетична: шахрайські ціни в ній задані як частка від типової, тому ознака, що міряє саме цю частку, майже ідеально відновлює правило, за яким дані створено. На справжніх оголошеннях правила ніхто не оголошує, ознака ловить його лише частково, і AUC 0.75 там уже вважається доброю здобиччю. Прийом справжній, а от розмір виграшу тут — тепличний.
Решта два переклади показують, що прийом не чарівний. «Ціна ÷ памʼять» дає взаємну інформацію 0.063 проти 0.069 у сирої ціни — тобто нічого: розкид цін пояснює модель, а не памʼять. «Ціна − медіана» дає 0.160 — удвічі менше за відношення, бо різниця в 500 грн для Alfa A5 це половина ціни, а для Gamma X Ultra округлення. Звідси правило: коли величини відрізняються на порядки, ділять; коли живуть в одному масштабі — віднімають.
А «вік телефона» не спрацював зовсім: AUC 0.535 при 0.5 у чесної монети. Логіка була правильна — шахраєві зручніше ховатись за старою моделлю. Дані сказали «ні». Так буває частіше, ніж хочеться, і саме тому ознаки міряють, а не проголошують.
АгрегатиОзнаки, зібрані по групі
«Типова ціна» з попереднього розділу — це агрегатна ознака: ми розбили таблицю на групи, порахували щось усередині кожної й приклеїли результат назад до кожного рядка. У pandas це одна конструкція:
Різниця між agg і transform тут принципова. agg
віддає таблицю «одна група — один рядок»; transform віддає стовпець тієї
самої довжини, що й вихідна таблиця. Ознакою може стати лише друге.
Що робить агрегатна ознака
Три кроки: розбити на групи, порахувати всередині групи, повернути число кожному рядку.
Групувати можна не тільки за моделлю. Ось що дали чотири різні агрегати:
| агрегатна ознака | кореляція | AUC | MI |
|---|---|---|---|
| середнє відхилення ціни в оголошеннях цього продавця | +0.611 | 0.928 | 0.151 |
| середня година публікації цього продавця | −0.293 | 0.703 | 0.089 |
| скільки оголошень подав цей продавець | +0.211 | 0.654 | 0.020 |
| медіанна ціна цієї моделі й року | −0.034 | 0.512 | 0.006 |
Дві речі в цій таблиці варті окремої уваги.
Найсильніший агрегат — не про ціну, а про продавця. «Середнє відхилення ціни в оголошеннях цього продавця» дає AUC 0.928. Одне дивне оголошення буває випадковістю, а коли в акаунта дивні всі — це вже профіль. Групувати за обʼєктом, який породжує рядки, — прийом, що працює майже завжди: продавець, користувач, магазин.
Найслабший агрегат — той, без якого нічого не вийшло б. Медіанна ціна моделі сама по собі марна: AUC 0.512, тобто монета. Дорогі моделі шахраї беруть не частіше за дешеві. Але саме вона стоїть у знаменнику найкращої ознаки всієї теми. Мораль: ознака може бути нічим окремо й усім у складі відношення, і саме тому відбирати ознаки по одній, дивлячись лише на її власну кореляцію, — небезпечно.
Техніка тут та сама, що в темі 07 і в темі 39 курсу Python. Нове тут одне питання: «за яким полем групувати, щоб вийшло осмислене порівняння».
ЧасЩо дістати з дати
У повному вивантаженні дошки є стовпець, якого ми досі не чіпали:
опубліковано — момент публікації з точністю до хвилини, скажімо
2024-01-04 23:03.
Найпоширеніша дія з такою колонкою — і найгірша — перевести її в число: компʼютер зберігає час як кількість секунд від 1970 року. Стовпець виходить пристойний на вигляд. Порахуємо його корисність: кореляція +0.044, AUC 0.539. Практично нуль.
Причина видна, щойно спитаєш, що це число означає: «наскільки пізно подано оголошення», і тільки. Структура доби, тижня й сезону в ньому є, але захована в молодших розрядах, і жодна модель не здогадається розкласти секунди на години. Сира дата як число марна не тому, що в даті мало інформації, а тому, що вся вона злиплась в одну величину.
Розібрати дату — означає видати кожну складову окремим стовпцем.
Сира дата проти розібраної
Ліворуч — те, що дає перетворення в число. Праворуч — те саме після розбору на складові. Числа — кореляція з таргетом на нашій дошці.
Стандартний набір такий: рік, місяць, число, день тижня, година, «вихідний чи ні», «скільки днів минуло від опорної дати». Останнє особливо корисне, коли важлива не сама дата, а проміжок: «днів від реєстрації акаунта до публікації» — майже готова ознака ризику.
На нашій дошці більшість складових виявились порожніми. Рік у всіх однаковий — константа, викидаємо. Місяць дав +0.042, день тижня −0.091, взаємна інформація в обох нуль. А от година публікації дала кореляцію −0.332 і взаємну інформацію 0.291 — більше, ніж будь-яка вихідна колонка. Медіанна година чесного оголошення — 13-та, шахрайського — 3-тя.
Пастка, через яку година працює гірше, ніж могла б
Розділення на око разюче, а кореляція лише −0.332. Причина в тому, що година як число бреше про відстані: для моделі 23 і 0 — це два краї шкали, найдальші одна від одної величини, хоча між ними одна хвилина.
Ніч у нас саме там, де шкала розривається: 22, 23, 0, 1, 2, 3, 4. Половина нічних оголошень має найбільші номери годин, половина — найменші, і спроба сказати «ризик тим вищий, чим більша година» розсипається.
Година на прямій і година на колі
Постав дві години й порівняй, яку відстань між ними бачить модель на прямій шкалі та яку — після циклічного кодування.
Розвʼязок — покласти годину не на пряму, а на коло. Замість одного стовпця «година» робимо два:
Буквально: ми беремо циферблат і записуємо координати кожної години на ньому. У 23-ї це (−0.26, +0.97), у 0-ї — (0.00, +1.00): вони поруч, бо на циферблаті поруч. У 13-ї — (−0.26, −0.97): та сама перша координата, зовсім інша друга. Ось навіщо потрібні обидва стовпці — сам синус не відрізняє 23 від 13, сам косинус не відрізняє 23 від 1.
Що це дає в числах. Кореляція година_cos з таргетом — +0.727,
AUC — 0.982, замість −0.332 і 0.684 у сирої години. Одне й те саме поле, той самий
момент часу: змінилось тільки те, у якому вигляді його показали.
ВзаємодіїДві ознаки, які працюють лише разом
Повернімось до головної ознаки теми й подивимось на неї збоку. Вона зроблена з двох чисел: ціни оголошення й типової ціни моделі. Порахуємо, чого варте кожне окремо.
Це і є взаємодія (interaction): комбінація двох ознак несе те, чого немає в жодній із них окремо. Ознака А не відрізняє класи, ознака Б майже не відрізняє — а їхнє відношення відрізняє майже ідеально.
Найкраще це видно на площині. Відклади типову ціну по одній осі, ціну оголошення — по другій, і подивись на ту саму хмару точок трьома способами.
Одна вісь, друга вісь, обидві разом
1 100 оголошень. Перемкни погляд: спершу подивись на кожну ознаку окремо, потім на площину.
На одній осі — дві криві, які лежать одна на одній. На площині — коридор чесних оголошень уздовж діагоналі й два згустки рожевого: під коридором ті, хто заманює знижкою, над ним — ті, хто ставить захмарну суму. Жодна вісь окремо їх не відділяє, бо вони відрізняються не значенням, а співвідношенням.
Практичний висновок: коли жодна ознака нічого не дає, це ще не означає, що даних мало. Часто це означає, що ти не поставив питання до пари ознак. Комбінують множенням (площа = довжина × ширина), діленням (щільність = маса ÷ обʼєм) і зіставленням категорій. Операцію диктує зміст задачі, а не перебір.
СкількиСкільки ознак треба
Спокуса після перших вдалих ознак очевидна: наробити ще пʼятдесят. Логіка здається залізною — зайва ознака в найгіршому випадку буде проігнорована. Насправді кожна зайва ознака коштує, і ось найпростіша демонстрація ціни.
Додамо до нашої таблиці 50 стовпців чистого шуму — випадкових чисел, які не мають до шахрайства жодного стосунку за побудовою. Порахуємо кореляцію кожного з таргетом:
Прочитай останній рядок ще раз. Осмислена ознака «вік телефона» дала 0.040 — менше, ніж найкращий з пʼятдесяти випадкових стовпців. Чим більше ознак ти перебираєш, тим сильніший найкращий випадковий результат — і тим більша ймовірність, що ти візьмеш його за відкриття.
Це не збіг і не наслідок невдалого зерна. Найбільше з багатьох випадкових чисел само собою більше за кожне з них окремо — і росте воно разом із тим, скільки чисел ти витягнув. Порахуймо, наскільки саме.
Скільки «сили» видає чистий шум
Для кожної кількості стовпців: найбільша за модулем кореляція серед них, коли звʼязку немає за побудовою. 1 100 рядків, частка одиниць у таргеті 0.139, медіана по 400 повторах.
Ось і пряма відповідь на питання розділу. Ознак треба стільки, щоб найкраща випадкова кореляція лишалась помітно нижчою за найслабшу ознаку, яку ти збираєшся брати всерйоз. На наших 1 100 рядках десяток ознак дає планку шуму 0.053, а дві сотні — 0.088: у першому випадку ознака з |r| = 0.15 явно щось знає, у другому доводиться ще й показувати, що вона не збіг. Планка залежить не лише від кількості ознак, а й від кількості рядків — вона падає приблизно як корінь із них, тож на десяти тисячах рядків ті самі двісті ознак дадуть уже близько 0.029. Звідси й робочий орієнтир: кілька десятків рядків на кожну ознаку. Тисяча рядків — до двох-трьох десятків ознак; сто тисяч — сотні.
Друга біда має назву: прокляття розмірності (curse of dimensionality). На прямій сотня точок стоять щільно; на площині ті самі сто точок уже розкидані; у просторі з пʼятдесяти ознак кожна з них — самотній острів, і поняття «схожі обʼєкти» перестає працювати. Розгорнуто це буде далі в курсі, коли дійдемо до моделей, що спираються на відстані; поки досить відчуття: з кожною новою ознакою даних потрібно більше, а їх не додається.
Як відбирати
За кореляцією. Найдешевше: порахувати |r| кожної ознаки з таргетом і відкинути хвіст. Пастка вже названа двічі: кореляція не бачить нелінійного, і ознака «ціна ÷ типова» з її +0.018 полетіла б у смітник першою.
За взаємною інформацією. Те саме, але лінійкою, яка бачить більше. Коштує дорожче й теж не всесильна: MI рахує звʼязок однієї ознаки з таргетом, тому пари, які працюють лише разом, вона так само пропустить.
Здоровим глуздом. Спитати себе, чи можеш ти пояснити словами, чому ця ознака має щось знати про відповідь. Якщо пояснення немає, а число красиве — це привід не радіти, а шукати помилку. Наступний розділ якраз про такий випадок.
ВитікВитік: ознака, що знає відповідь
У темі 08 ми вже зустрічали витік даних (data leakage): колонка «скарг» була звʼязана з таргетом майже ідеально, бо скарга зʼявляється після того, як шахрайство викрито. Там витік уже лежав у даних — лишалось його помітити. Інженерія ознак додає гірший різновид: витік, який ти створюєш власноруч.
Цільове кодування
Колонка «продавець» містить 440 різних значень, і звичайне кодування категорій дало б 440 нових стовпців. Тому напрошується інша ідея: замінити кожного продавця часткою шахрайських оголошень серед його власних. Це називається цільовим кодуванням (target encoding), і виглядає воно бездоганно:
Один рядок, жодних 440 стовпців, і ознака одразу показує чудову кореляцію. Проблема в тому, що серед 440 продавців 121 подав рівно одне оголошення, і для нього «середнє по його оголошеннях» — це сам таргет цього рядка. Не схожий на нього, не приблизно рівний — буквально він.
Звідки береться витік у цільовому кодуванні
Один продавець, одне оголошення. Ліворуч — наївний розрахунок по всій таблиці. Праворуч — той самий розрахунок, зроблений лише на навчальній частині.
Числа з підпису варто перечитати. Ознака з чистої вигадки за наївного розрахунку виглядає сильнішою за майже все, що ми знайшли в розділах 02-04. Не тому, що вона щось знає, а тому, що ми поклали в неї відповідь і самі ж її звідти дістали.
На справжній колонці «продавець» картина мʼякша, напрямок той самий: наївне кодування дає на тестовій частині 0.657, чесне — 0.303. Половина «сили» ознаки була позичена з відповідей.
Правило
Воно те саме, що й для будь-якої передобробки даних — масштабування, заповнення пропусків, кодування категорій: усе, що рахується з даних, рахується лише на навчальній частині. Медіани, середні, карти кодування, межі викидів — усе. Порядок дій такий:
Поділити таблицю на навчальну й тестову частини, як у темі 03 — до того, як ти порахуєш першу агрегатну ознаку.
Побудувати карту «категорія → число» тільки за навчальними рядками.
Застосувати цю карту й до навчальної, і до тестової частини. Категоріям, яких у навчальній частині не було, підставити загальне середнє.
Перевірити результат на тих рядках, яких карта не бачила. Якщо ознака стала вдесятеро слабшою, вона такою й була.
Кодування поза фолдом
Поділ полагодив вимірювання, але не саму ознаку. Подивись, де ми зараз: на тестових рядках карта чесна, бо їх під час її побудови не було. А на навчальних рядках усе лишилось як було — кожен із них брав участь у власному середньому. Модель учиться саме на них, отже саме туди підказка й потрапляє.
Порахуймо це прямо. Беремо той самий вигаданий «код регіону» — 448 випадкових міток на 1 100 рядків, жодного звʼязку з шахрайством за побудовою — і дивимось кореляцію кодованої ознаки з таргетом на тих самих рядках, з яких карта й будувалась:
Нуль перетворився на 0.610, і жодний поділ цього не змінить: це число живе всередині навчальної частини. Ліки одні — зробити так, щоб мітка рядка ніколи не потрапляла в число, яке цей рядок отримає.
Спосіб перший: виключення себе
Виключення себе (leave-one-out) — найбуквальніше прочитання цієї вимоги: рахуючи середнє для рядка, викинь із суми його власну мітку.
Символи тут такі: yi — мітка самого рядка (0 або 1),
s — сума міток усієї групи, тобто скільки в ній шахрайських оголошень,
m — скільки рядків у групі. Віднімання прибирає власну мітку з чисельника,
а m − 1 — самий рядок зі знаменника.
Порахуймо руками на одному продавці. У нього шість оголошень, із них два
шахрайські: m = 6, s = 2.
| оголошення | мітка | наївно (s ÷ m) | виключення себе |
|---|---|---|---|
| перше | 1 | 0.33 | (2 − 1) ÷ 5 = 0.20 |
| друге | 0 | 0.33 | (2 − 0) ÷ 5 = 0.40 |
| третє | 1 | 0.33 | (2 − 1) ÷ 5 = 0.20 |
| четверте | 0 | 0.33 | (2 − 0) ÷ 5 = 0.40 |
| пʼяте | 0 | 0.33 | (2 − 0) ÷ 5 = 0.40 |
| шосте | 0 | 0.33 | (2 − 0) ÷ 5 = 0.40 |
Власної мітки в числі більше немає — і саме тому пастка стала гіршою. Подивись на
останній стовпець: усередині цієї групи є рівно два значення, і менше з них
завжди означає шахрайське оголошення. Ознака не просто підказує відповідь — вона
підказує її навиворіт, і будь-яка модель, яка вміє відрізнити один регіон від іншого,
прочитає цю підказку без зусиль. Формула це й каже: код відрізняється рівно на
1 ÷ (m − 1) залежно від того, нуль там чи одиниця — у нашому прикладі
рівно на 0.20.
Найпідступніше те, що звичайна кореляція цього не бачить: на тому самому «коді регіону» виключення себе дає r = −0.001, тобто ідеально чистий нуль. Ознака виглядає бездоганно й водночас містить відповідь.
Спосіб другий: поза фолдом
Правильний спосіб виключає не рядок, а цілий блок рядків разом із ним. Навчальну
частину ріжуть на кілька рівних шматків; їх звуть фолдами (fold) — так
само це слово стоїть і в іменах бібліотечних інструментів, як-от KFold. Для
рядків кожного фолда карту будують лише за рештою фолдів. Пʼять фолдів — пʼять різних карт, і жоден рядок
не бачить тієї, у побудові якої брав участь. Це і зветься кодуванням поза
фолдом (out-of-fold target encoding). Той самий поділ на фолди ми зустрінемо ще
раз у темі 18, уже заради вимірювання
якості.
Чому блок кращий за окремий рядок. Коли викидають один рядок, число, яке він отримує, залежить від того, яка саме в нього мітка, — звідси й дзеркальна підказка вище. Коли викидають цілий фолд, усі рядки цього фолда з цієї групи отримують однакове число, хоч би які мітки в них були. Показати пальцем на конкретний рядок воно вже не може.
Три способи порахувати те саме середнє
Один продавець, шість його оголошень, дві мітки з шести — шахрайські; навчальна частина порізана на три фолди по два рядки. Дивись на останній стовпець кожного блоку: що саме отримує рядок як свою ознаку.
Звідси третя, спільна проблема: група з двох рядків дає середнє з одного числа, а це ще не статистика. Тому на практиці код підмішують до загального середнього тим сильніше, чим менша група, — цей прийом зветься згладжуванням (smoothing). Це те саме за задумом, що й згладжування Лапласа в наївному Баєсі: замість того щоб довіряти оцінці, зробленій на кількох спостереженнях, її притягують до загальної. Поки досить запамʼятати головне: цільове кодування — не просто ще один спосіб закодувати категорію, а прийом із вбудованою пасткою, і чесний поділ на train і test закриває лише половину її.
ГлуздГлузд проти автоматики
Оскільки ознаки — це формули, напрошується їх генерувати. Найвідоміший спосіб —
поліноміальні ознаки: дописати до вихідних стовпців їхні квадрати й усі
попарні добутки. У scikit-learn це PolynomialFeatures, один
виклик.
Порахуймо, що вийде на нашій дошці. Чотири числові стовпці дають 4 квадрати й 6
попарних добутків — 10 нових ознак, у восьми з яких змісту немає взагалі. Потрібної нам
взаємодії — ціна ÷ медіана по моделі й року — серед них немає й бути не
може: у ній бере участь величина, якої в таблиці не існує, поки ти сам її не порахуєш.
Це і є межа автоматики: вона комбінує те, що вже є, а найкращі ознаки роблять із того, чого ще немає. Медіана по групі, коридор «удвічі дешевше», ознака «в цього продавця дивні всі оголошення» — усе це наслідки того, що хтось подумав про предметну область, а не перебрав добутки.
Друга проблема перебору — арифметична. Десять вихідних стовпців дають 55 поліноміальних ознак другого степеня, двадцять — 210. Ми щойно бачили, що серед 50 випадкових ознак знаходиться одна з |r| = 0.061; серед 210 знайдеться краща. Автоматична генерація видає багато сміття на одну корисну ознаку — і сміття це виглядає пристойно.
| що маємо | що робимо | навіщо |
|---|---|---|
| величина, у якої є природний масштаб | ділимо на цей масштаб | число стає порівнянним між різними обʼєктами |
| дві величини в одному масштабі | віднімаємо | різниця читається в тих самих одиницях |
| величина, важлива в обидва боки | беремо модуль логарифма відношення | «вдвічі більше» й «вдвічі менше» стають одним числом |
| категорія з багатьма рядками | агрегат по групі через groupby | рядок дізнається про свою групу |
| дата або час | розбираємо на складові | структура доби й тижня перестає бути захованою |
| циклічна величина | синус і косинус кута | кінець циклу стає сусідом його початку |
| дві ознаки, кожна безсила | добуток або відношення | ловимо те, чого немає в жодній окремо |
| категорія з високою кардинальністю | цільове кодування — тільки на train | 440 стовпців стискаються в один, ціною ризику витоку |
ПідсумокЩо забрати з теми
Ми почали з таблиці, у якій найсильніша ознака давала кореляцію 0.116, а ціна — нуль. Не додавши жодного нового джерела даних, ми отримали дві ознаки з AUC 0.990 і 0.982 — обидві з полів, які лежали в таблиці від початку.
- Ознака — це переклад. Якщо ти щось розумієш про задачу, а в стовпцях цього немає, — модель цього не дізнається.
- Ділити й віднімати. Сира величина без масштабу майже завжди марна. Порядки різні — діли; масштаб один — віднімай.
- Групувати.
groupby+transformдає рядку знання про його групу. Найсильніші агрегати — по обʼєкту, що породжує рядки. - Дату розбирати. Секунди від 1970 року — це не ознака. Година, день тижня, «скільки минуло» — ознаки. Циклічне ставимо на коло.
- Міряти, а не проголошувати. Три лінійки, у кожної своя сліпа пляма. Ознака «вік телефона» здавалась розумною й не спрацювала.
- Боятись гарних чисел. Ознака, що зненацька дала блискучий результат, частіше протікає, ніж працює. Усе, що рахується з даних, рахується на train.
І одне, чого ця тема свідомо не робить. Ми жодного разу не сказали «ознака X підняла якість моделі на стільки-то» — бо моделей ми ще не проходили. Коли дійдемо до них, буде видно, що ознака такої сили змінює результат більше, ніж заміна алгоритму на складніший. Поки що це обіцянка, і перевіримо ми її числами пізніше.
Далі в блоці лишається одна тема — PCA, і вона про зворотний бік того, чим ми щойно займались. Тут ми стовпці додавали; там їх стискатимуть, шукаючи, скільки насправді незалежних напрямків ховається в матриці ознак, яка розрослась. А потім — моделі, і перше, що ти зробиш із кожною з них, — подаси їй саме ту матрицю ознак, яку навчився будувати тут. Розвідку, передобробку й інженерію ознак підряд, на одній задачі від сирого файлу до висновків, ти пройдеш у темі 30.