malyj_gorgan: (Default)
[personal profile] malyj_gorgan
Нижченаписане -- це як табличка множення для всякої людини, яка хоч колись працювала близько до модної останні чверть століття теми "машинне навчання", ака, Machine Learning (ML). Якщо ви це все знаєте, пропустіть, але комусь може і цікаво буде.

Значить, класифікатор, це така штука, яка рахує відображення з вектора ознак (feature vector) на бінарний (0/1) ярлик (label). (Наприклад, вектор ознак -- це шкільні оцінки абітурієнта Гарварду, його вік, зріст, вага, стать, раса, колір очей, банківський рахунок батьків, кількість сторінок, які читає за рік, кредитний скор і рейтинг продавця на Ебей, а ярлик -- чи поступить абітурієнт в Гарвард, чи ні) Як саме класифікатор це робить -- залежить, є багато алгоритмів, а я вам роповім, як цей класифікатор оцінюють. Більшість класифікаторів (не всі, кластерінг ні, але від банальної лінійної регресії до нейронних мереж) мають проміжний крок, коли ви знаєте якусь одномірну неперервну величину між 0 і 1 як функцію вектора ознак. Найчастіше це -- імовірність, що ярлик з таким вектором ознак буде 1. (Хоча на практиці може бути якась [0,1]->[0,1] функція цеї імовірності, але то вже умняк.) Словом, той самий скор (score) s, про який я недавно писав. Сам ярлик рахують, вибираючи порогове значення, якщо s менше, то ми класифікатор каже "0", інакше "1".
Результат роботи класифікатора оцінюється через так звану матрицю неоднозначностей (confusion matrix): 2×2 матриця, яка для перевіряльного набору даних (validation dataset), тобто, набору даних, де ми знаємо і ознаки, і ярлики, каже нам чотири числа (з лівого верхнього кута за годинниковою стрілкою):
  * правильно відгадані нулі (true negatives або TN)
  * помилки першого роду: те що насправді нуль, а класифікатор обізвав одиничкою (false positives або FP)
  * правильно відгадані одинички (true positives або TP)
  * правильно відгадані помилки другого роду, те, що насправді один, але класифікатор назвав нулем(false negatives або FN))
Відповідно, точність класифікатора міряють за відносною кількістю вгаданих нулів і одиничок. Найпопулярніші метрики:
(a) Повнота, вона ж чутливість (recall=sensitivity) R=TP/(TP+FN) -- яку частину одиничок класифікатор правильно знаходить
(b) Влучність (precision) P=TP/(TP+FP) -- яка частина з того, що класифікатор назве одиничкою, вгадана правильно
(c) Специфічність (specificity) S=TN/(TN+FP) -- яку частину нулів класифікатор правильно знаходить
(d) Хибнопозитивний рівень (false positive rate) FPR=1-S -- яку частину нулів класифікатор хибно оголосить одиницями.

З цим, якщо подумати, все більш-менш ясно. Тільки це вимірює точність остаточного класифікатора, але не дає повною картинки про класифікаційну модель. Памʼятаєте, там був скор і порогове значення? Так от, саме модель і скор є основним результатом машинно-навчального проєкту, а вже вибір порогу і матриця неоднозначностей рахується виходячи з моделі плюс міркувань бізнесу. Тому що у всіх неідеальних випадках є якісь хибні нулі і одинички, відповідно, поріг вибирається з міркувань відносної ціни FP і FN на наявних даних. А сама модель, коли порахована, описується не просто кількома цифрами, а графіком. ВІрніше, навіть двома: якість класифікатора описується ROC-кривою, а доречність класифікатора описується розподілом даних вздовж скора. Нижче -- пояснення на прикладах абсолютно реального класифікатора, який я написав для одної зі своїх робіт, він прямо зараз в продакшені живе.

ROC-curve (ROC-крива, receiver operator characteristic curve),
Крива, яка показує, яка чутливість відповідає різним хибнопозитивним рівням. НИжче -- реальна ROC-крива. Класифікатор дуже точний (такі в продакшні рідко трапляються, я прямо пишаюся), тому картинка з кривою має додаткову вставку, де показують повноту для зовнім низьких значеннях FPR.
roc_curve_with_insert
Фактично, на цьому графіку ви вибираєте поріг: вирішуєте, що можете собі дозволити один FP на тисячу, після чого бачите: з таким ризиком помилки першого роду, я вгадаю 60% одиничок правильно. Ще раз нагадаю -- це дуже точний класифікатор, в житті доводиться миритися з набагато вищим FPR.

Розподіл даних за скором
Це не характеристика моделі, а вимір того, наскільки дана модель добре підходить для певного набору даних. Ось, все з того ж самого реального прикладу:
score_distribution
Це, знову ж таки -- дуже хороший розподіл. Видно, що більшість зразків матимуть або дуже високий скор, або дуже низький, причому, дані збалансовані (там і справді порядку 60% одиниць... а у світі часто трапляються набори даних, відносна кількість нулів до одиничок або навпаки -- порядку 1000/1 або і більше). Словом, з таким розподілом можна край боронити. Шкода, що вони рідко такі гарні бувають.

От і казочці кінець ;)

Date: 2025-08-08 06:38 am (UTC)
kondybas: (Default)
From: [personal profile] kondybas
Коли я займався поштою і воював із спамом, довелося вивчати питання класифікаторів. Та й скоринг доводилося тюнити.

Date: 2025-08-08 04:24 pm (UTC)
kondybas: (Default)
From: [personal profile] kondybas
Та ж ніби проблему спаму пофіксили. Не принципово, звичайно, бо особливості протоколу. Але ж сукупність доволі простеньких технік дозволяє зарубати 99.999% спаму. Простий байєс-фільтр у спамассассіні працює дуже добре.

Date: 2025-08-08 05:05 pm (UTC)
kondybas: (Default)
From: [personal profile] kondybas
Тут головний момент в тому, що є різне сприйняття інфоматеріалів, і те, що для когось є софт-спамом, для іншого - цінна кореспонденція. Це автоматично натякає на рішення - багаторівнева фільтрація. Щось треба фільтрувати безумовно для всіх і всюди, щось треба фільтрувати на рівні вузлового МТА, а щось має фільтруватися персонально, на стадії LDA. Ясне діло - із фідбеком та "м'яким деферром", коли сумнівні листи потрапляють у фолдер "спам" для подальшого вирішення людиною спам/не спам.

Я свого часу саме таке і робив, і воно дуже добре працювало. Як не дивно, найбільш цінним компонентом всієї системи був пул добре відомих спам-ганів, які струячили виключно спам. В поганих системах їм або дають відлуп на стадії HELO, або приймають та одразу дропають їхні листи. В мене був зовсім протилежний підхід. З точки зору спамерів я був лохом, якому можна було слати що завгодно звідки завгодно. Неіснуючий домен? Приймаю! Листи з домена в обхід доменного МТА? Приймаю! Порушуєш DKIM/DMARC? Приймаю! Шлеш з мого ж домену мені ж іззовні без автентифікації? Приймаю! Відправник з чорного списку? Приймаю! Особливо я любив відправників, які починали передачу листа одразу після конекту, оминаючи фазу HELO - просто аж пищав від захвату.

Все це добро одразу додавалося до блеклиста, а їхні листи сипалися на навчання байєса. Фактично, спамери самі постачали мене матеріалом для ML. Раз на тиждень мені слало листа із списком 20 найбільш активних спам-доменів, які не були внесені в блеклист. Я його проглядав очима, інколи навіть ходив дивитися, що там і, якщо то був черговий спамхост - додавав його у блеклист. Але кілька разів то були просто погано настроєні МТА, які я допоміг законопатити.

Date: 2025-08-08 08:04 pm (UTC)
kondybas: (Default)
From: [personal profile] kondybas
В гугломейла є хоч і вбога, але LDA-фільтрація, можна створити фільтр, який буде дропать всяке промо від лінкеда, залишаючи лиш те, що представляє інтерес.

Date: 2025-08-08 08:18 am (UTC)
From: [personal profile] ichthuss
О, хотів принагідно проконсультуватись, якщо це не надто нахабно з мого боку.

У мене є задачка на класифікацію для особистих цілей. Мені регулярно доводиться записувати і оброблювати записи любительських акустичних концертів, і сама занудна частина обробки - це виділити в записі "музику", "конферанс", "оплески". Хочу це діло автоматизувати. Я приблизно уявляю, в який бік рухатись, але, можливо, я щось пропускаю. В цілому задачка геть проста, але є нюанси, що роблять її не цілком тривіальною для людини, далекої від датазнавства.

1. Лейбли не взаємовиключні (оплески можуть накладатись на конферанс чи на музику)
2. Це не зовсім задача класифікації, бо треба не просто віднести запис до однієї з категорій, а знайти початок і кінець. Тобто детекція з класифікацією.
3. Для найкращого результату точність межі має принципове значення, в ідеалі хотілося б точності в межах 10 мс.

Який шлях я бачу найпростішим:
- ділимо на 20-мс фрагменти з 10-мс перекриттям (можливо, 50-мс з 25-мс перекриттям)
- в якості фіч беремо перші N частот з log(abs(FFT(signal)) (орієнтовно 0-10kHz)
- засовуємо це в якийсь класифікатор (підозрюю, що там навіть нейронка не знадобиться, щось простіше спрацює). В принципі, класифікатор можна абстрагувати і міняти в процесі експериментів
- будуємо графік "скор(час)" шляхом інтерполяції (лінійно чи кубічним сплайном) і знаходимо точки перетину порогу.

Підозрюю, що достатньо буде класифікувати всі фрейми незалежно (сумніваюсь лише в якості розділення "сольний спів" - "мовлення", там, можливо, знадобиться пам'ять з попередніх фрагментів). Не впевнений, наскільки добре така штука поводитиме себе при комбінації лейблів.

Щось порадите ML-ламеру?

Date: 2025-08-09 03:26 pm (UTC)
From: [personal profile] ichthuss
Спасибі велике!

Деякі думки на тему.

0. В моєму застосуванні (переважно хоровий спів) важливі для класифікації частоти рідко спускаються нижче 70 Гц, Тому я не бачу особливої проблеми з короткими кліпами. Інтуїтивно мені здається, що якщо включити довільний 50-мс фрагмент запису в нескінченному повторі, людина дуже легко відрізнить оплески від музики і від мовлення. Хоча думка розділити завдання на грубішу (по часу) класифікацію і точне знаходження меж makes sense.

1. Ну, з signal processing'ом я, якраз, дружу добре. З тією його частиною, де йде чітка математика, а не шаманство типу "подаємо щось на вхід, не знаємо, що всередині, отримуємо вихід, міняємо всередині самі не знаємо що". Щодо кастомізованих характеристик - можливо, справді є сенс подумати, хоча мені здається, що сабжеві класи будуть легко відрізнятись тупо по спектрограмі.

1а. ОК, доведеться вникати в те, що таке вейвлети, принаймні щоб оцінити, наскільки воно треба. 20 років назад було нецікаво і ліньки, зараз теж нецікаво і ліньки, але, може, буде корисним.

2. Ну, labeled dataset я самостійно підготую, я все одно майже те ж саме роблю кожен раз при обробці.

3.(а) - не зовсім зрозумів процес. Мова про те, що я починаю аннотувати файл, а програма по ходу діла на цьому тренується і одразу дає класифікацію, яку я потім лише підтверджую або спростовую?
(б) о, це важливий момент. А в яку, орієнтовно, розмірність входу слід цілитись?

Date: 2025-08-09 05:08 am (UTC)
From: [personal profile] sassa_nf
А чи включає в себе термін "музика" барабани? Бо ритм може бути кілька beats per second, і сампли десятки мс довжиною просто не в змозі їх зловити.

Те ж і про оплески. Ритм оплесків низькочастотний за побудовою. Звісно, кожен окремий ляпас видасть багато різних частот, але сукупно це ж низькочастотний сигнал.

Date: 2025-08-09 02:31 pm (UTC)
From: [personal profile] ichthuss
Конкретно в моєму випадку "музика" - це на 90% акапельний хоровий спів, інколи з додаванням перкусії, решта 10% - теж хоровий спів, але з інструментальним супроводом (найчастіше фортепіано).

Оскільки виступи в більшості випадків відбуваються в залах з непоганою акустикою, то реверберація після оплесків ще деякий час (навряд чи менше секунди) буде зберігати приблизно ту ж саму частотну структуру, тому конкретно тут я великої проблеми не бачу.

Date: 2025-08-09 04:00 am (UTC)
From: [personal profile] sassa_nf
Дякую. А є якась інтуїція що як називають? Бо я завжди плутаю, хто precision, хто sensitivity, а хто specificity?

А, а ще можна згадати, що коли кажуть, який точний, скажімо, сканер відбитків пальців на айфоні, то називають одну цифру. І що то є повний б..., тобто, маркетинг. Бо одним числом якість класифікатора описати неможливо.

Date: 2025-08-10 10:53 am (UTC)
From: [personal profile] sassa_nf
> Specificity -- how specific you are to the disease, наскільки добре ти хворобу ізолюєш, тобто, з усіх здорових, скількох діагностуєш правильно = diagnosed negative / all negativеs.

От оце один із моїх спотикачів. Інтуїтивно хочеться сказати "наскільки вірно знаходить хворих саме на цю хворобу серед усіх хворих", а ділять негативи. Хоча звісно, це не про те, а про чи ти роздаєш діагноз всім підряд, чи ні.

А є якийсь layman's термін для FPR чи якийсь показник схожий на ROC? Я малюю ROC, а люди скаржаться, що вони "не математики", і їм не зрозуміло, як цим користуватись. (Задача така: автоматично знайшов комбінації параметрів, які "пояснюють" походження проблеми, і треба показати, на які комбінації слід звернути увагу. Для цього малюю TPR, FPR, Lift, ROC - мені зрозуміло, але як пояснити не спеціалістам?)

Date: 2025-08-11 06:44 am (UTC)
From: [personal profile] sassa_nf
Прикольно. Я таке роблю, але малюю фігури різної форми: коло перетинається із квадратом. Щоб не виникало спокуси, що похилу можна відкалібрувати, "виструнчити" вертикально. Тоді також наочніше питання різного розміру класів.

Але цього разу у мене задача зовсім інша, то треба подати інформацію про якість кількох класифікаторів - типу, чим якість одного відрізняється від іншого. Я малюю щось на зразок ROC кривої, хоча звісно виходить не суцільна крива, а просто точки на площині. І треба пояснити користувачам, на що це вони дивляться.

Так би мовити, автомат знаходить пів сотні початкових кроків до аналізу, а сам аналіз потрібно виконувати вручну. Ну, так щоб розуміти, з яких кроків починати, треба розуміти, що кожна точка означає. Скажімо, "класифікатор" x=y має такий-то показник TP та FP, а "класифікатор" x=y ∧ p=q - отакі-то. Додаючи p=q ми зменшуємо TP, але і значно зменшуємо FP.

Щось таке.

Так от, як назвати TP я розумію, а як назвати FP я не придумаю.

Date: 2025-08-12 01:16 pm (UTC)
From: [personal profile] sassa_nf
Ну, юз-кейс - порівняти кілька різних класифікаторів, щоб користувач міг обрати, яким з них довіряти і в чому.

Це не те саме, для чого ROC curve винайшли, але оскільки порівняльні характеристики класифікаторів - це TPR та FPR, то я їх порівнюю на такій самій площині, як і ROC curve. І замислююсь, як пояснити, що таке FPR.

Так то я можу пояснити, що звертати увагу варто на лівий верхній кут, а решта для контексту - тобто, наскільки гірші інші класифікатори, і ща якими ознаками. Але ж люди питають, що за осі Х та У

Date: 2025-08-13 05:16 am (UTC)
From: [personal profile] sassa_nf
Ок, це згодиться для однієї хвороби.

У нас - а ну, що сталося за минулий місяць? 100500 хворих загалом, 20800 перехворіли та видужали, 50200 хронічно хворі.

Із них: виглядає як 10% - жертви епідемії А, 12% - новий штам Б, 30% аутоімунні через ген В, решту не можемо пояснити.

Date: 2025-08-14 05:04 am (UTC)
From: [personal profile] sassa_nf
Типу того, так.

Маємо 100500 хворих. Які пояснення?

Один каже: епідемія А
Другий каже: хибна комбінація генів Б
Третій каже....

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

TPR=FPR - значить, нічого особливого, просто випадковість, раз пропорція хворих і здорових із тими факторами однакова.

Date: 2025-08-14 08:50 pm (UTC)
From: [personal profile] sassa_nf
100500 хворих. Так, розподіл ймовірностей.

А Баєсівська мережа потребує догляду? Я б волів щось на зразок моделі, де я можливо поглядав би раз чи інколи, а воно само регулярні пояснення показувало, чим можна пояснити картину захворювань на сьогодні.

Date: 2025-08-15 06:01 pm (UTC)
From: [personal profile] sassa_nf
Дякую. Треба буде попрацювати над цим ретельніше.

Думаю, тут ще треба буде спочатку почистити дані як слід. Бо у нас timeline, а треба визначити "ось один випадок захворювання". А, і ще треба почитати, як безперервні показники побити на категоричні. (Ха, або навпаки)

Тоді на цю мережу подавати симптоми разом.

Гм, не зовсім розумію, де тут етап тренування. У нас із відомими діагнозами поки що швах. Тобто, вони існують, але не прив'язані до симптомів.

Profile

malyj_gorgan: (Default)
malyj_gorgan

January 2026

S M T W T F S
     1 23
45678910
11121314151617
18192021222324
25262728293031

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 6th, 2026 01:00 pm
Powered by Dreamwidth Studios