Машинне навчання · Блок 2 · Тема 09

Передобробка даних

Дірки знайдено, викиди перелічено, підозріла колонка викрита. Тепер треба ухвалити десяток рішень — і кожне з них змінює те, що ти зрештою дізнаєшся.

У попередній темі ми пройшли дошку оголошень наскрізь і жодного разу нічого в ній не змінили. Вийшов список знахідок: дванадцять повних дублікатів; стовпець памʼяті, який pandas прочитав як текст; сто одна порожня ціна, причому порожня не випадково; сорок вісім порожніх значень стану, а ці якраз випадкові; сімдесят вісім оголошень за межею міжквартильного розмаху, серед яких є і колекційні флагмани, і одруки; і колонка «скарг», яка виявилась витоком.

Список є. Тепер його треба виконати — і саме тут починається найцікавіше. Бо жодна з цих дірок не має правильної відповіді в підручнику.

01 / МотивРішення, а не рецепти

Передобробка (preprocessing) — це перетворення таблиці, якою вона приїхала, у таблицю, з якою можна працювати: без дірок, без тексту там, де потрібні числа, з ознаками, що вимірюються в порівнянних одиницях. Звучить як технічна робота. Насправді це найзмістовніша частина всієї задачі, і ось чому.

Візьмімо одну дірку — порожню ціну в оголошенні. Що з нею робити?

Три однорядкові команди, три різні твердження про світ. Код не покаже різниці: усі три відпрацюють без попереджень і повернуть охайну таблицю. Різниця виявиться пізніше — у відповіді, яку ти отримаєш.

Тому головна думка теми проста й неприємна: у передобробці немає операцій, є рішення. Кожен виклик fillna, кожне видалення рядка, кожне кодування категорії — це припущення, яке ти вносиш у дані власноруч. Далі все, що ти дізнаєшся, буде дізнане разом із цим припущенням, і відрізнити одне від одного вже не вийде.

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

Почнімо з двох кроків, у яких рішень майже немає. Дублікати: дванадцять рядків повторюються повністю, вони прийшли зі злиття двох вивантажень, і ми їх прибираємо — лишається 1 200 рядків. Тип стовпця: памʼять записана як 128 ГБ, ми відрізаємо суфікс і переводимо в число. Після цих двох кроків пропусків у ціні стає 100, а не 101: один із дублікатів був рядком без ціни. Далі кожен крок уже вимагатиме вибору.

Що треба знати заздалегідь. Механіку pandas — fillna, dropna, get_dummies, groupby — ми розібрали в темі 34 курсу Python, а векторні операції над матрицею ознак — у темі 07. Тут ми говоримо не про те, як викликати метод, а про те, що кожен виклик стверджує про дані.

02 / ПропускиПропуски: три шляхи

Із дірками в таблиці можна зробити рівно три речі: викинути рядок, викинути стовпець або чимось заповнити. Розберімо всі три на наших числах.

Шлях перший: викинути рядки

Найчесніший на вигляд варіант: не вигадувати нічого, працювати лише з повними рядками. Порахуймо, скільки їх у нас.

рядків усього 1 200 рядків без ціни 100 рядків без стану 48 рядків, де немає обох 3 ────────────────────────────────────── лишиться після dropna() 1 055

Втрачено 145 рядків — восьма частина таблиці. Але подивімось не на кількість, а на те, які це рядки:

рядківшахрайськихчастка
було1 20019516.3 %
лишилось1 05513512.8 %

Разом із 145 рядками ми викинули 60 шахрайських оголошень із 195 — майже третину всього, заради чого будується задача. І не випадкову третину: саме ту, де шахрай не назвав ціни. Дірки в цій колонці не рівномірні по таблиці, тому й видалення рядків б'є не рівномірно.

Видалення рядків годиться, коли пропуски рідкісні (одиниці відсотків) і випадкові. У нас другої умови немає.

Шлях другий: викинути стовпець

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

У нас ціна порожня у 8.3 % рядків, стан — у 4.0 %. Обидві колонки лишаємо.

Шлях третій: заповнити

Найпоширеніший вибір — і найбільше можливостей помилитись. Для числової колонки беруть середнє або медіану; для текстової — найчастіше значення (моду) або окрему категорію «невідомо».

Між середнім і медіаною вибір не косметичний. У темі 08 ми бачили, що ціни розподілені скошено: середнє 6 498 грн, медіана 4 000 грн, і дешевших за середнє оголошень аж 68.6 %. Тобто «середнє оголошення» — це обʼєкт, якого майже не буває. Заповнивши сотню дірок числом 6 498, ти вставляєш у дані сто копій неіснуючого телефона, та ще й у ту частину шкали, де реальних оголошень мало. Медіана менш вигадлива: 4 000 грн — це справді типова ціна на цій дошці.

Правило, яке варто запамʼятати: чим сильніше розподіл скошений, тим надійніша медіана. Середнє тягнуть за собою кілька великих значень — у нас це чотири колекційні Gamma X і два одруки; медіана про них навіть не знає.

А для стану заповнення модою («добре», 483 рядки з 1 152) підіймає частку цього значення з 41.9 % до 44.2 % — тобто робить найчастішу категорію ще частішою. Іноді це прийнятно. Часто чесніше створити окрему категорію невідомо: вона нічого не вигадує й чесно каже, що значення не було.

Інтерактив 1 · Чотири способи закрити дірку

Розподіл цін на нашій дошці, кошик 1 250 грн, вісь обрізана на 25 000 грн. Рожеве — справжні оголошення; яскравий стовпчик — сто значень, яких у даних не було і які ми щойно вигадали.

рядків
шахрайських
найвищий кошик
вигаданих у ньому
Прогони всі чотири. «Видалити» не чіпає форму розподілу взагалі — шкода тут не в картинці, а в лічильниках: із 195 шахрайських оголошень лишається 139. «Середнє» ставить сто копій 6 498 ₴ туди, де справжніх оголошень удвічі менше, — виходить другий пік, якого в даних немає. «Медіана» ставить ту саму сотню в густу частину шкали: надбудова нижча, зате кошик 3 750–5 000 ₴ стає найвищим на всій картинці. «Невідомо» заповнює тим самим числом, але додає окрему колонку-прапорець: значення підставлене, а факт, що його не було, у таблиці лишився.

03 / ПрапорецьПропуск як ознака

Тепер найважливіші двісті слів теми. Поверніться до знахідки теми 08: серед оголошень без ціни шахрайських 56.0 %, серед оголошень із ціною — 12.6 %. Різниця в чотири з половиною рази.

Дивись, що це означає. Ціни немає — значення втрачене, відновити його нічим. Але сам факт відсутності — не втрачений. Він лежить у таблиці, доступний, і він відрізняє шахрая від чесного продавця краще, ніж багато справжніх колонок. Треба лише його записати:

дошка["ціни_немає"] = дошка["ціна"].isna().astype(int)

Один рядок — і в таблиці зʼявилась нова ознака. Її звʼязок із таргетом можна виміряти одразу: кореляція ціни_немає з міткою шахрайства — 0.325. Для порівняння, та сама кореляція для стану_немає−0.021, тобто нічого. Один пропуск інформативний, другий ні, і розрізняє їх одне число.

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

Порядок, який рятує ознаку. Спершу прапорець, потім заповнення. Якщо зробити навпаки, прапорець вийде з самих нулів, і ти навіть не зрозумієш, що щось втратив: помилки не буде, буде просто колонка без інформації.

І узагальнення, ширше за нашу дошку. Пропуск інформативний скрізь, де його створює поведінка людини, а не збій техніки. Не вказаний дохід у заявці на кредит; не заповнене поле «попереднє місце роботи»; порожній результат аналізу, який лікар не призначив, бо вважав зайвим. У всіх цих випадках прапорець значення_немає — безкоштовна ознака. Робити його завжди не варто (для випадкових пропусків це шум), але перевірити, чи він щось несе, коштує один рядок.

04 / КатегоріїТекст у числа

Наступна дірка в наших даних не порожня, а текстова. Колонки «модель» і «стан» — слова, а майже все, що ми будемо з даними робити, вимагає чисел: додавання, множення, відстані. Значить, слова треба перевести в числа. Способів два, і вони стверджують дуже різні речі.

Порядкове кодування

Порядкове кодування (ordinal encoding) — це «пронумеруймо значення». Alfa A5 → 0, Alfa A7 → 1, Beta 12 → 2, і так далі. Колонка була одна — колонка й лишилась, дешево та компактно.

Тепер скажи вголос, що це стверджує. Що Beta 12 (2) удвічі більша за Alfa A7 (1). Що відстань від Alfa A5 до Alfa A7 така сама, як від Gamma X до Gamma X Ultra. Що Beta 12 лежить рівно посередині між Alfa A5 і Gamma X. Останнє легко перевірити: медіанні ціни цих трьох моделей — 1 845, 4 215 і 9 350 грн, а середина між крайніми — 5 598. Тобто код каже «посередині», а насправді Beta 12 на третину дешевша за середину.

І найгірше: числа тут беруться з назв, а не зі світу. Додай на дошку дешеву модель «Delta Z» — за алфавітом вона дістане код 6, найбільший, тобто опиниться на місці найдорожчого телефона. Дані не змінились — змінилась лише вигадана нами шкала.

Але для колонки «стан» порядкове кодування — правильний вибір, і це важливо не переплутати. «Задовільне → 0, добре → 1, дуже добре → 2, нове → 3» — тут порядок є насправді, він у самих значеннях, і числа його не вигадують, а записують. Ознаки з внутрішнім порядком звуться порядковими (ordinal), і саме для них цей спосіб і придуманий.

Пряме кодування

Пряме кодування, воно ж one-hot — це «колонка на кожне значення». Замість однієї колонки «модель» зʼявляються шість, у кожному рядку рівно одна одиниця, решта нулі. Ніякого порядку не стверджується: усі шість моделей рівновіддалені одна від одної, і це чесно.

Схема 1 · Одна колонка проти шести

Ліворуч — те, що робить пряме кодування: одна одиниця в рядку, і жодних тверджень про порядок. Праворуч — те, що стверджує порядкове кодування, поруч із тим, як воно є насправді.

Права половина — уся суть заперечення. Порядкове кодування розставляє моделі рівномірно, бо числа 0…5 стоять рівномірно. Справжні медіанні ціни ростуть ривками: між двома сусідніми моделями буває 965 ₴, а буває 3 060 ₴. Для «стану» такої претензії немає: там порядок справжній, і шкала його лише записує.

За пряме кодування платять шириною таблиці. Шість моделей — шість колонок; чотири значення стану плюс «невідомо» — пʼять колонок. Разом одинадцять колонок замість двох. Поки що дрібниця. Але уяви колонку «місто» з чотирма сотнями значень: чотириста колонок, у кожній майже самі нулі, і в більшості з них — одиниця в трьох-чотирьох рядках з тисячі. Це називають високою кардинальністю (high cardinality), і пряме кодування на ній розсипається: таблиця роздувається, а користі майже немає.

Виходи є. Найпростіший — залишити найчастіші двадцять значень, а решту зсипати в категорію «інше». Другий, спокусливіший — цільове кодування (target encoding): замінити кожне місто середнім значенням таргета в цьому місті. Виглядає це чудово: одна колонка замість чотирьохсот, та ще й одразу «корисна». Пастка теж є, і велика — саме тому цільове кодування ми розберемо окремо, у наступній темі, разом із захистом від неї. Поки що досить знати, що воно існує і що вмикати його не думаючи не можна.

05 / МасштабГривні, дні й гігабайти

Числа в нашій таблиці міряються в різних одиницях, і розкид у них різний на порядки: ціна — тисячі гривень, вік акаунта — сотні днів, памʼять — десятки гігабайтів, рік — чотиризначне число, яке взагалі майже не змінюється. Поки кожну колонку розглядають окремо, це не заважає. Щойно їх починають порівнювати між собою — заважає одразу.

Найпростіший приклад такого порівняння — схожість двох оголошень. Візьмімо три справжні рядки з нашої дошки.

модельцінавік акаунта
базовеBeta 12 Pro4 620 грн459 днів
АAlfa A74 650 грн273 дні
БGamma X5 480 грн466 днів

Яке з двох ближче до базового? Порахуймо різниці, як їх рахують у школі — по теоремі Піфагора, ніби це дві координати точки:

крок 1 · у сирих одиницях

Для А різниці такі: 30 гривень і 186 днів. Для Б: 860 гривень і 7 днів.

до А = √(302 + 1862) = 188  ·  до Б = √(8602 + 72) = 860

Виходить, що А ближче. Але подивись, що ми щойно зробили: оголосили, що 860 гривень — це «більше», ніж 186 днів. Гривні порівняли з днями, ніби це однакові величини.

крок 2 · у частках власного розкиду

Виміряймо кожну різницю не в її одиницях, а в тому, наскільки вона велика для своєї колонки. Розкид цін на дошці — 8 685 грн, розкид віку акаунтів — 407 днів.

860 грн = 0.10 розкиду цін  ·  186 днів = 0.46 розкиду віку

Тепер картина перевертається. 860 гривень — це дрібниця на тлі того, як ціни взагалі гуляють. А 186 днів — майже пів розкиду віку акаунтів, тобто справді інший продавець. Ближчим виявляється Б.

Те, що ми щойно зробили руками, і зветься масштабуванням. У NumPy воно займає один рядок на всю матрицю ознак одразу — рівно той broadcasting, який ми розбирали в темі 07. Двох способів вистачає на майже все.

Стандартизація (standardization): від кожного значення відняти середнє колонки й поділити на її стандартне відхилення. Результат каже «на скільки розкидів це значення вище або нижче за типове». Для ціни 4 620 грн при середньому 6 498 і відхиленні 8 685 виходить (4 620 − 6 498) / 8 685 = −0.22: трохи дешевше за середнє. Нуль означає «рівно середнє», одиниця — «на один розкид вище».

Мінімакс (min-max): відняти мінімум і поділити на розмах, тобто втиснути колонку рівно у відрізок від 0 до 1. Для тієї самої ціни: (4 620 − 130) / (95 000 − 130) = 0.047.

Другий спосіб виглядає охайнішим, і саме тут ховається його вада. Розмах ціни на нашій дошці задають два значення: найдешевший телефон за 130 грн і колекційна Gamma X за 95 000. Одне-єдине оголошення розтягує шкалу так, що 81.7 % усіх цін лягають нижче 0.1 — 95 % таблиці тиснеться в пʼятій частині відрізка. Стандартизація теж не любить викидів, але переживає їх спокійніше: під |z| < 1 потрапляє 92.3 % оголошень, і шкала лишається читабельною.

Інтерактив 2 · Хто ближчий до базового оголошення

Базове оголошення — у центрі. Точки А і Б показані як зсув від нього по двох осях. Кола проведені через А і через Б: чиє коло менше, той і ближчий. Масштаб обох осей однаковий, тому кола можна порівнювати очима.

відстань до А
відстань до Б
ближче
у скільки разів
Це те місце, де перемикач змінює відповідь, а не картинку. «Як є» — ближчим виявляється А, бо різниця у 860 ₴ вважається більшою за різницю в 186 днів. Обидва способи масштабування дають протилежну відповідь — і між собою вони згодні: Б ближчий і в стандартизації, і в мінімаксі. Різняться вони не висновком, а тим, як лягають числа: у мінімаксі всі три оголошення тиснуться до нуля, бо шкалу розтягнув один колекційний телефон за 95 000 ₴.

Коли масштабування потрібне, а коли ні? Правило таке: воно потрібне скрізь, де колонки складають, множать або порівнюють між собою — у відстанях, у сумах із коефіцієнтами, у будь-якому геометричному міркуванні. Воно не потрібне там, де кожну колонку розглядають окремо й лише порівнюють значення всередині неї.

06 / ВикидиЩо робити з викидами

У темі 08 ми знайшли 78 оголошень за межею 1.5·IQR і зʼясували головне: викид — не синонім помилки. Чотири колекційні Gamma X за 82–95 тисяч гривень справжні, два оголошення з зайвим нулем — ні, а правило міжквартильного розмаху їх не розрізняє. Тепер треба вирішити, що з ними робити. Варіантів чотири.

Лишити як є. Правильно завжди, коли значення справжнє й ти вмієш із ним працювати. Колекційний телефон за 95 000 грн — частина ринку, і викидати його означає брехати про ринок.

Обрізати (winsorize): усе, що вище межі, замінити самою межею. Значення лишається великим, але перестає тягнути на себе арифметику. На наших цінах обрізання по верхній межі 16 061 грн опускає середнє з 6 498 до 5 557 грн, а максимум — до тієї самої межі. Рядки цілі, розподіл цілий, крайні значення приборкані.

Прибрати рядок. Годиться лише тоді, коли ти впевнений, що це помилка запису. Два оголошення з зайвим нулем — саме такий випадок; краще за видалення тут хіба що виправлення на 8 350 і 7 600 грн. Автоматичне видалення всього за межею коштувало б нам 75 рядків, серед них — увесь дорогий кінець ринку.

Логарифмувати. Найелегантніший варіант, коли викиди справжні, а розподіл скошений. Замість самої ціни беруть її логарифм, і величезні значення підтягуються до решти самі, без жодного правила й жодної межі.

крок 1 · що робить логарифм

Десятковий логарифм відповідає на питання «скільки нулів». Ціна 1 000 грн дає 3, ціна 10 000 — 4, ціна 95 000 — 4.98. Тобто розрив у сто разів перетворюється на розрив у дві одиниці.

крок 2 · що з цим стало на наших даних

Скошеність (skewness) — одне число, що міряє, наскільки хвіст витягнутий у правий бік. Нуль означає симетрію.

скошеність цін = 5.32  →  скошеність log10(ціни) = 0.10

Було сильно скошено — стало практично симетрично. І ще одна перевірка: середнє логарифмів, повернуте назад у гривні, дає 4 075 — тобто майже точно медіану 4 000, а не роздуте середнє 6 498.

Схема 2 · Та сама колонка до й після логарифма

Ліворуч — ціни як є: пік притиснутий до лівого краю, довгий хвіст, у який не влазить вісь. Праворуч — десятковий логарифм тих самих цін, уся колонка без обрізань.

Жодного значення не видалено й не змінено — змінено лише шкалу. Ліва картинка змушена обірвати вісь на 25 000 ₴, інакше понад чотири пʼятих оголошень злиплися б у перших двох стовпчиках. Права вміщає всю колонку, від 130 ₴ до 95 000 ₴, і найдорожчі телефони перестають бути окремим світом — вони просто праворуч.
Логарифм не безкоштовний. По-перше, він не приймає нуля й відʼємних значень — тому часто беруть log(1 + x). По-друге, усе, що ти далі порахуєш, буде порахувано в логарифмах, і назад у гривні воно повертається не завжди очевидно. Це чесна ціна, і платити її варто свідомо.

07 / ВитікВитік через передобробку

А тепер найдорожча помилка в усій темі. Вона не в тому, що ти робиш із даними, а в тому, у якому порядку.

Ось як виглядає природний хід думки. «Спершу приведімо таблицю до ладу: заповнимо дірки медіаною, масштабуємо колонки, закодуємо категорії. Тепер дані чисті — можна ділити на навчальну й тестову частини й міряти якість». Звучить бездоганно. І це помилка.

Медіана, якою ти заповнив дірки, порахована по всій таблиці — включно з рядками, які за хвилину стануть тестовими. Середнє й відхилення для масштабування — теж. Тобто в момент, коли ти нібито «ще не бачив» тестову частину, вона вже встигла вплинути на кожне число в навчальній. Тема 03 називає це прямо: тест має грати роль майбутнього, якого ще немає. А тут майбутнє підглянуло саме в себе.

Правило одним рядком. Усе, що навчається на даних, навчається лише на train. Медіана для заповнення, середнє й відхилення для масштабування, список категорій, межі обрізання викидів, будь-які пороги — усе це числа, вивчені з даних. Тест їх лише отримує.

Покажімо, скільки це коштує. Візьмімо задачу, яку можна розвʼязати без жодної моделі: позначити підозрілі оголошення за ціною. З теми 08 ми знаємо, що звʼязок ціни з шахрайством U-подібний — підозрілі і найдешевші, і найдорожчі. Отже, правило таке: оголошення підозріле, якщо його ціна нижча за поріг П1 або вища за поріг П2. Пороги ми не вигадуємо — підбираємо за даними, окремо для кожної пари «модель + стан», бо для Alfa A5 і для Gamma X Ultra «дешево» означає різні суми. Груп виходить 30, порогів — 60 чисел, і всі вони вивчені з таблиці.

Далі ділимо дошку на 900 навчальних рядків і 300 тестових і міряємо якість на тестових через precision, recall і F1. Двома способами.

Інтерактив 3 · Порядок, у якому рахують

Ті самі 1 200 рядків, той самий поділ, те саме правило. Різниця лише в тому, звідки взято числа, які правило вивчило. Оцінка — на тих самих 300 тестових рядках.

медіана заповнення
F1 на тесті
precision
recall
Різниця — третина оцінки. Неправильний порядок обіцяє F1 0.643, правильний дає 0.483. Обидва числа виміряні на одних і тих самих 300 рядках, тим самим правилом. Перше з них — те, що ти напишеш у звіті; друге — те, що станеться насправді. Прикро тут не так те, що обман великий, як те, що він завжди в один бік: на 20 різних поділах неправильний порядок завищив оцінку 20 разів із 20.

Звідки береться саме така величина? Порогів 60, а груп, у яких вони підбираються, аж 30, і в найменшій із них усього пʼять рядків. На пʼятьох рядках «найкращий поріг» — це поріг, підігнаний під ці пʼять рядків. Коли вони всі були доступні під час підбору, правило їх просто запамʼятало; коли доступні лише навчальні, воно мусить вгадувати. Чим більше чисел ти вивчаєш із даних, тим дорожчий витік:

що вивчаємонеправильноправильнозавищення
2 числа: спільні пороги0.3600.333+0.027
12 чисел: пороги на модель0.6150.565+0.050
60 чисел: модель і стан0.6310.483+0.147

Числа в таблиці — середні F1 по 60 різних поділах, щоб не залежати від щасливого випадку. Нижній рядок — той, що на картинці вище. Верхній показує головну підступність: коли вивчених чисел мало, завищення дрібне, його не помічають — і саме тому звикають робити неправильно.

08 / КонвеєрПорядок дій і конвеєр

Отже, порядок. Кроки бувають двох сортів, і сортувати їх треба саме за цією ознакою:

Схема 3 · Де проходить лінія поділу

Зверху — кроки, які роблять із кожним рядком те саме. Далі — поділ. Знизу — кроки, які спершу щось вивчають, і напрямок, у якому вивчене має право рухатись.

Одна стрілка й одна перекреслена стрілка — це вся тема. Від train до test знання йде: медіана, середнє, відхилення, список категорій. Від test до train не йде нічого й ніколи. Порушення цієї межі не викликає ні помилки, ні попередження — воно викликає лише хорошу цифру у звіті.

Тримати це в голові на десяти колонках і чотирьох перетвореннях — справа безнадійна. Тому в scikit-learn є конвеєр (Pipeline) — обʼєкт, який складає всі кроки передобробки в один ланцюжок і має рівно два методи: fit — «вивчи все, що треба вивчити» — і transform — «застосуй вивчене». Далі ти пишеш конвеєр.fit(train) — і підмішати туди тест уже нічим: до тестової частини застосовується transform, а він нічого не вчить, він лише підставляє вивчене.

Конвеєр — не турбота про красу коду. Це те, що фізично унеможливлює помилку з попереднього розділу: не існує способу випадково застосувати до тесту статистику, яку вивчили на тесті. У нашому зошиті конвеєр із чотирьох кроків перетворює сім вихідних колонок на 16 числових і, навчений на 900 навчальних рядках, запамʼятовує медіану ціни 3 975 грн — навчальну, а не загальну 4 000. Ця різниця в 25 гривень і є вся чесність вимірювання.

09 / ПідсумокТаблиця рішень

Зберімо тему в один аркуш. Третя колонка тут найважливіша: у передобробці не буває безкоштовних дій, і питання завжди не «що правильно», а «чим я готовий заплатити».

Таблиця · Проблема, способи і ціна кожного

Жоден рядок не має єдиної правильної відповіді. Правильність визначається тим, що означають дані, а не тим, що зручніше набрати.

проблемаспособичим платиш
Пропуски, яких мало й вони випадковівидалити рядки; заповнити медіаною або модоювидалення — рядками; заповнення — штучним піком у розподілі
Пропуски, повʼязані з таргетомпрапорець «значення немає» плюс заповненнязайва колонка; забудеш прапорець — втратиш ознаку назавжди
Пропусків понад половину стовпцяприбрати стовпецьусім, що в ньому було, разом із самим фактом пропуску
Категорія без порядкупряме кодуванняшириною таблиці: колонка на кожне значення
Категорія з порядкомпорядкове кодуваннятвердженням, що кроки між значеннями однакові
Категорія з сотнями значень«інше» для рідкісних; цільове кодуваннязлиттям різних речей в одну; ризиком витоку
Колонки в різних одиницяхстандартизація; мінімаксчитабельністю сирих чисел; мінімакс — беззахисністю перед викидом
Викид, який справжнійлишити; обрізати; логарифмуватиобрізання — величиною; логарифм — простотою тлумачення
Викид, який є помилкоювиправити; прибрати рядокрядком і часом на розбір
Статистики для всіх цих кроківрахувати лише на train, через конвеєрнічим — це єдиний рядок таблиці без ціни
Останній рядок — єдиний, у якому немає вибору. Решта дев'ять залежать від того, що означають твої дані. Цей не залежить ні від чого: порядок «спершу поділ, потім навчання статистик» правильний завжди.

10 / ДаліЩо далі

Таблиця, з якою ми почали, тепер придатна до вжитку: без дублікатів, з числами замість тексту, без дірок, з ознаками в порівнянних одиницях і без колонки «скарг», яка була витоком. Але зверни увагу на дещо: стовпців у ній стало більше, ніж було. Ми додали ціни_немає, і ця вигадана з порожнечі колонка виявилась інформативнішою за деякі справжні.

Це вже не прибирання. Це інженерія ознак (feature engineering) — тема наступної лекції. Там ми будемо не лагодити колонки, а робити нові: ціна відносно типової для цієї моделі; вік телефона замість року випуску; ознаки, зібрані групуванням; і цільове кодування разом із захистом від пастки, яку ми щойно пообіцяли розібрати. З того самого U-подібного звʼязку ціни з шахрайством, який зіпсував нам кореляцію в темі 08, там вийде одна колонка, у якій звʼязок стане прямим.

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

Далі в практиці. У practice.ipynb ти збереш ту саму дошку, пройдеш кожне рішення з цієї теми по черзі й надрукуєш його наслідки, додаси колонку-прапорець, закодуєш категорії обома способами й порівняєш, масштабуєш числа, відтвориш витік із сьомого розділу до цифри — і збереш усе в конвеєр, який робить це правильно сам.

Далі в темі

Теорію прочитано. Тепер закріпи її на практиці.