Выброс (outlier) простыми словами

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

Короткое объяснение

Выброс (outlier) — это значение, которое сильно отличается от остальных в выборке.

Например: 99% клиентов тратят 1 000–5 000 ₽, а один потратил 500 000 ₽. Этот один — выброс.

Выбросы могут быть реальными (богатый клиент) или артефактом (баг, ошибка ввода). И то, и другое важно правильно обработать.

Откуда берутся выбросы

  • Реальные редкие случаи: кит, крупный enterprise-клиент, необычная покупка
  • Ошибка ввода: кассир ввёл 100000 вместо 10000
  • Технический сбой: двойной платёж, дублированная транзакция
  • Фрод / боты: искусственно накрученные транзакции
  • Другой контекст: корпоративная покупка в B2C-продукте

Почему выбросы важны

Они искажают среднее

Зарплаты 5 сотрудников: 60, 65, 70, 75, 500 тыс. Среднее: 154 тыс. Медиана: 70 тыс.

Среднее обманывает — «типичная зарплата», которой нет ни у кого.

Они портят A/B-тесты

Один кит с покупкой на миллион может сделать «тест значимым», хотя реально продукт не изменился.

Они влияют на ML-модели

Линейная регрессия, k-means, PCA — все чувствительны к выбросам.

Иногда выбросы — инсайт

Самые прибыльные клиенты = выбросы по revenue. Их нельзя просто «удалить» — нужно понять.

Как найти outlier

1. Z-score (Z-оценка)

Сколько стандартных отклонений от среднего.

Z = (x − mean) / SD

Обычно:

  • |Z| > 2 — подозрительно
  • |Z| > 3 — скорее всего выброс
import numpy as np
z = (x - np.mean(x)) / np.std(x)
outliers = np.where(np.abs(z) > 3)

Минус: само среднее и SD зависят от выбросов → unreliable.

2. IQR (Interquartile Range) — классический метод

Считаем квартили:

  • Q1 (25-й перцентиль)
  • Q3 (75-й перцентиль)
  • IQR = Q3 − Q1

Границы выбросов:

  • Lower: Q1 − 1.5 × IQR
  • Upper: Q3 + 1.5 × IQR

Всё за пределами — outlier.

Q1 = np.percentile(x, 25)
Q3 = np.percentile(x, 75)
IQR = Q3 - Q1
lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR
outliers = x[(x < lower) | (x > upper)]

Робастен к выбросам (в отличие от Z-score).

3. Перцентили (кастомные пороги)

«Выброс = топ 1% или низ 1%»:

lower = np.percentile(x, 1)
upper = np.percentile(x, 99)
outliers = x[(x < lower) | (x > upper)]

Полезно, когда нужен прагматичный подход.

4. Визуально

  • Box plot — сразу видно outliers (точки за «усами»)
  • Scatter plot — видно аномалии
  • Histogram — длинный хвост

5. ML-методы

  • Isolation Forest — для многомерных данных
  • DBSCAN — кластеризация; точки вне кластеров = outliers
  • LOF (Local Outlier Factor) — локальные аномалии

Что делать с outlier

1. Удалить

Если это ошибка ввода — просто удалить или пометить.

Риск: не удаляйте «неудобные» данные только потому, что они мешают модели.

2. Winsorize — заменить на границу

Значения выше P99 → заменяем на P99.

from scipy.stats.mstats import winsorize
winsorized = winsorize(x, limits=[0.01, 0.01])

Сохраняет структуру распределения, но смягчает хвосты.

3. Log-трансформация

Сдвигает распределение к нормальному, «сжимает» большие значения.

x_log = np.log1p(x)  # log(1+x), safe для x=0

Хорошо работает для чеков, выручки, времени.

4. Использовать медиану вместо среднего

Медиана устойчива к выбросам.

Для сравнения групп — Mann-Whitney U-test вместо t-test.

5. Сегментировать

Разделить на «киты» (топ 1%) и «обычные». Анализировать отдельно.

6. Оставить как есть

Если outlier — реальный (кит приносит 30% выручки) — удалять нельзя. Нужно понять.

В A/B-тестах

Выбросы — боль A/B-тестов с тяжёлым хвостом (чек, time on site, LTV).

Решения:

  • Winsorize перед тестом (P99 → P99)
  • Мann-Whitney вместо t-test
  • CUPED — снижает дисперсию через ковариату
  • Stratified sampling — стратифицируем по pre-period активности
  • Log-трансформация

На собесе

Типичный вопрос:

«Как вы работаете с выбросами?»

Хороший ответ:

  1. Проверить, не ошибка ли это (ввода, техническая, дубли)
  2. Использовать IQR или percentile для детектирования
  3. Решить стратегию: удалить / winsorize / сегментировать
  4. В A/B — Mann-Whitney или CUPED при тяжёлых хвостах
  5. Документировать решение (почему удалили / оставили)

Плохой ответ: «Удалить и всё».

Частые ошибки

Ошибка 1. Удалять, потому что «странное»

Если нет причины считать ошибкой — не удалять. Это реальный сигнал.

Ошибка 2. Использовать только Z-score

На нарушении нормальности Z-score ненадёжен. IQR робастнее.

Ошибка 3. Не документировать

Через месяц никто не вспомнит, почему 200 записей вы удалили. Комментируйте в коде и в отчётах.

Ошибка 4. «Очистим данные и будет лучше»

Реальная выручка — с выбросами. «Чистая» средняя — обман бизнеса.

Ошибка 5. Одинаковая обработка для всех контекстов

Для A/B винсоризация. Для клиентской аналитики — сегментировать. Для ML — зависит от задачи.

Связанные темы

FAQ

Как определить «правильный» метод?

IQR — дефолт для одномерных метрик. Percentile — прагматичный подход. ML-методы для сложных данных.

Удалять выбросы в A/B?

Не удалять «злые» данные задним числом. Использовать winsorize или Mann-Whitney.

2 SD или 3 SD?

|Z|>3 — строже. |Z|>2 включает много false positives (в нормальном распределении 5%).

Можно ли просто медиану использовать?

Часто да. Медиана не «боится» выбросов.


Тренируйте статистику — откройте тренажёр с 1500+ вопросами для собесов.