Фрея · риск-менеджер необанка «Монетка»
Антифрод принёс три правила: блокировать карту, если у клиента 5 отказов из 40 операций; тревога, если за день прошло больше 10 покупок электроники; и «странный чек» в ресторане по трём отклонениям от среднего. Вы сами говорили, что z-оценка на чеках врёт. Какие из правил годятся?
В прошлом уроке распределение цены предмета мы описывали таблицей. Но многие величины в аналитике устроены одинаково, и для них есть готовые распределения с формулами. В scipy.stats каждое из них живёт объектом с одинаковыми методами. Разберём пять самых ходовых на трёх правилах Фреи.
Бернулли: один отказ
Одна операция по карте либо проходит, либо банк её отклоняет. За полгода по картам «Монетки» было 71 277 операций, банк отклонил 2042. Шанс отказа p = 2042 / 71277 = 0,0286.
Величину, которая принимает значение 1 с вероятностью p и 0 с вероятностью 1 - p, называют распределением Бернулли. Купил или не купил, кликнул или нет, отказ или нет: всё это Бернулли. Матожидание у него p, дисперсия p * (1 - p).
Биномиальное: отказы из n операций
У клиента 203 за полгода 40 операций и 5 отказов. Если каждая операция отклоняется независимо с тем же шансом 2,86%, число отказов из 40 подчиняется биномиальному распределению с n = 40 и p = 0.0286:
from scipy import stats
p = 2042 / 71277
dist = stats.binom(40, p)
dist.mean(), dist.std() # (1.15, 1.06)
dist.pmf([0, 1, 2, 3, 4, 5]).round(4)
# array([0.3126, 0.3688, 0.2121, 0.0792, 0.0216, 0.0046])
pmf даёт вероятность ровно k отказов. В среднем у такого клиента 1,15 отказа, чаще всего ноль или один. Насколько редкость пять? Нужен хвост: пять или больше.
dist.sf(4) # 0.0055: P(X >= 5)
dist.sf(5) # 0.0009: P(X > 5), не то
sf(x) в scipy это вероятность строго больше x. Для «пять или больше» передают 4. С sf(5) ответ в шесть раз меньше, и клиент выглядит в шесть раз подозрительнее, чем есть.
Пять отказов из сорока случайно выпадают в 0,55% случаев. Выглядит как повод блокировать. Но клиентов 2000, и порог «реже 1%» у нас проходят семь человек. Если бы отказы у всех были чистой случайностью, такой порог на 2000 клиентах всё равно отметил бы до двадцати человек. Семь невезучих это обычный результат, а не банда мошенников. К тому, как проверять много гипотез сразу, вернёмся в уроке про ловушки A/B.
Пуассон: покупки электроники за день
Покупок электроники за день бывает от 1 до 15, и жёсткой верхней границы у этого числа нет. Когда событие редкое, а возможностей для него много (тысячи клиентов, каждый может купить ноутбук), число событий за период подчиняется распределению Пуассона. Параметр у него один: λ, среднее число событий за период.
import pandas as pd
daily = pd.read_csv("electronics_daily.csv")
x = daily["purchases"]
lam = x.mean() # 5.82: 1053 покупки за 181 день
stats.poisson.sf(10, lam) # 0.0355: P(X > 10)
Правило «больше 10 покупок» по Пуассону срабатывает в 3,55% обычных дней, примерно раз в месяц. В данных так и вышло: 8 дней из 181. Для тревоги, которая будит дежурного, это часто. Найдём порог, который обычный день переходит реже чем в 1% случаев:
stats.poisson.ppf(0.99, lam) # 12.0
stats.poisson.sf(11, lam) # 0.0163: P(X >= 12), больше 1%
stats.poisson.sf(12, lam) # 0.0070: P(X >= 13), меньше 1%
ppf(0.99) возвращает границу, ниже которой лежат 99% дней: P(X <= 12) >= 0.99. Двенадцать ещё обычное число, тревога начинается с тринадцати. За полгода такой день был один: 15 покупок.
У Пуассона есть простая проверка: дисперсия равна среднему. У нас дисперсия 7,23 при среднем 5,82, отношение 1,24. Данные разбросаны чуть сильнее Пуассона: в выходные покупают больше, 6,46 в день против 5,56 в будни. Модель годится для грубого порога, но доверять её дальним хвостам стоит осторожно.
урок из курса
Урок из курса «Аналитика данных с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.