Раздел 42 · Аналитика данных с нуля

Описательная статистика: медиана, перцентили и выбросы

middle~15 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Фрея · риск-менеджер необанка «Монетка»

Мне нужен лимит на подозрительные операции. Сколько тратит обычный клиент за раз? Только без «средней температуры по больнице». И скажи, какие покупки точно ненормальные.

Новый заказчик и новая база. Фрея отвечает за риски необанка «Монетка» и любит цифры без воды. В базе bank клиенты (clients), их карты (cards), полгода операций по картам (transactions) с кодом категории продавца и статусом, а ещё таблицы теста кешбэка, к которым мы придём в следующем уроке. Код категории это MCC: 5411 продукты, 5812 рестораны, 4111 транспорт, 5732 электроника. У операции три статуса: approved прошла, declined банк отклонил, reversed прошла и потом отменена.

Траты описываем только по approved: отклонённая операция это деньги, которые клиент не потратил.

Средняя температура по больнице

В палате десять пациентов. У девяти 36,6, у одного 41. Средняя температура 37,04: формально «все слегка температурят», на деле девять здоровы и один в беде. Среднее чувствительно к крайним значениям, медиана нет.

Медиана это значение, которое стоит ровно посередине, если выстроить все операции по сумме. В PostgreSQL её считают агрегатом с сортировкой внутри:

SELECT count(*) AS transactions,
       round(avg(amount_rub), 2) AS mean,
       percentile_disc(0.5) WITHIN GROUP (ORDER BY amount_rub) AS median
FROM transactions
WHERE status = 'approved';
 transactions |  mean   | median
--------------+---------+--------
        68241 | 1583.60 |    783

Среднее почти вдвое выше медианы. 73% операций меньше среднего: его тянут вверх редкие покупки электроники до 172 628 ₽ и снятие наличных. «Обычный клиент тратит за раз около 1600 ₽» это неправда, обычная операция около 800 ₽.

Перцентили: где кончается обычное

Медиана это частный случай перцентиля, 50-й. Для лимитов полезнее 95-й: граница, выше которой лежат только 5% операций.

В PostgreSQL две функции перцентиля, и разница важна:

  • percentile_cont(0.95) интерполирует: если нужная позиция падает между двумя значениями, вернёт точку между ними, например 4316,649999… ₽ у ресторанов. Такого чека никто не платил;
  • percentile_disc(0.95) возвращает ближайшее настоящее значение из ряда: 4317 ₽.

Для отчёта о чеках берём percentile_disc. Считаем по категориям, потому что «крупная покупка» в метро и в магазине электроники это разные суммы:

mccкатегорияоперациймедиана, ₽p95, ₽
5411продукты23 2338322 787
4111транспорт9 64963138
5814фастфуд и кофе8 0784411 103
5812рестораны5 9021 5424 317
6011наличные2 0215 40715 205
5732электроника1 0539 73846 952

Один общий лимит на все категории бессмыслен: для метро подозрителен уже чек в 300 ₽, для электроники нормален чек в 40 000 ₽.

урок из курса

Урок из курса «Аналитика данных с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.