Как работать с выбросами в данных? Какие методы обнаружения и обработки выбросов вы знаете?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Выбросы (Outliers): Обнаружение и обработка
Определение
Выброс (Outlier) — это значение, которое значительно отличается от остальных данных в наборе. Может быть результатом ошибки, особого события или подлинной аномалии.
Методы обнаружения выбросов
1. Метод трёх сигма (3-Sigma Rule)
Выброс = значение вне диапазона [mean - 3σ, mean + 3σ]
Пример:
Mean = 50, σ = 5
Нормальный диапазон: [35, 65]
Значение 100 → ВЫБРОС
SQL:
WITH stats AS (
SELECT
AVG(value) as mean,
STDDEV(value) as stddev
FROM data
)
SELECT *
FROM data
WHERE value > (SELECT mean FROM stats) + 3 * (SELECT stddev FROM stats)
OR value < (SELECT mean FROM stats) - 3 * (SELECT stddev FROM stats);
Плюсы: Простой, математичный, работает для нормального распределения Минусы: Не работает хорошо для асимметричных распределений
2. Метод IQR (Interquartile Range)
Q1 = 25-й процентиль
Q3 = 75-й процентиль
IQR = Q3 - Q1
Выброс = значение < Q1 - 1.5×IQR или > Q3 + 1.5×IQR
Пример:
Данные: [10, 12, 14, 16, 18, 20, 22, 100]
Q1 = 13, Q3 = 21, IQR = 8
Нижний порог = 13 - 1.5×8 = -3
Верхний порог = 21 + 1.5×8 = 33
Значение 100 > 33 → ВЫБРОС
SQL:
WITH quartiles AS (
SELECT
PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY value) as q1,
PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY value) as q3
FROM data
)
SELECT *
FROM data
WHERE value < (SELECT q1 FROM quartiles) - 1.5 * ((SELECT q3 FROM quartiles) - (SELECT q1 FROM quartiles))
OR value > (SELECT q3 FROM quartiles) + 1.5 * ((SELECT q3 FROM quartiles) - (SELECT q1 FROM quartiles));
Плюсы: Хорошо работает с асимметричными данными, робастный Минусы: Может пропустить мягкие выбросы
3. Метод процентилей
Выброс = значение < P5 или > P95
(или P1/P99, P10/P90 в зависимости от задачи)
Когда использовать: Когда нет нормального распределения
4. Z-score метод
z = (value - mean) / σ
Если |z| > 3 → выброс
(или > 2.5, > 2 в зависимости от чувствительности)
5. Локальный метод (DBSCAN, LOF)
Рассматривает соседние точки
Точка, окружённая непохожими значениями → выброс
Когда использовать: Когда есть кластеры в данных
Методы обработки выбросов
Способ 1: УДАЛИТЬ выброс
-- Удалить строки с выбросами
DELETE FROM data
WHERE value > mean + 3 * stddev
OR value < mean - 3 * stddev;
Когда использовать:
- Явная ошибка (отрицательная зарплата, дата рождения в будущем)
- Данные от спама/ботов
- Технический сбой
Плюсы: Простой Минусы: Теряем данные, может быть важно
Способ 2: ЗАМЕНИТЬ на другое значение
-- Заменить на mean
UPDATE data
SET value = (SELECT AVG(value) FROM data)
WHERE value > mean + 3 * stddev;
-- Заменить на median
UPDATE data
SET value = (SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY value) FROM data)
WHERE value > mean + 3 * stddev;
-- Заменить на Q3 (capping)
UPDATE data
SET value = (SELECT PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY value) FROM data)
WHERE value > mean + 3 * stddev;
Когда использовать:
- Не хотим потерять строку
- Есть частичные данные (например, покупки с датой, но без суммы)
Плюсы: Сохраняем данные Минусы: Может искажать распределение
Способ 3: ТРАНСФОРМАЦИЯ данных
import numpy as np
# Логарифмическая трансформация (для правого skew)
data_log = np.log(data)
# Box-Cox трансформация (автоматическая)
from scipy.stats import boxcox
data_transformed, lambda_param = boxcox(data)
# Квадратный корень
data_sqrt = np.sqrt(data)
SQL эквивалент:
SELECT
LN(value) as log_value, -- натуральный логарифм
SQRT(value) as sqrt_value
FROM data;
Когда использовать: Когда данные имеют skew (асимметричны)
Способ 4: WINDSORIZATION (обрезка)
Заменить экстремальные значения на граничные (P95, P99):
SELECT
CASE
WHEN value > PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY value)
THEN PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY value)
WHEN value < PERCENTILE_CONT(0.05) WITHIN GROUP (ORDER BY value)
THEN PERCENTILE_CONT(0.05) WITHIN GROUP (ORDER BY value)
ELSE value
END as windsorized_value
FROM data;
Когда использовать: Когда хотим сохранить данные, но ограничить влияние выбросов
Способ 5: ОТДЕЛЬНЫЙ АНАЛИЗ
Анализировать выбросы отдельно как группу:
-- Главная группа (без выбросов)
SELECT AVG(value) as avg_main
FROM data
WHERE value BETWEEN mean - 3*stddev AND mean + 3*stddev;
-- Выбросы (отдельно)
SELECT AVG(value) as avg_outliers, COUNT(*) as outlier_count
FROM data
WHERE value > mean + 3*stddev OR value < mean - 3*stddev;
Когда использовать: Выбросы имеют смысл (VIP клиенты, специальные события)
Практические примеры
Пример 1: Revenue данные
-- Часто VIP клиенты создают "выбросы"
-- Не удаляем, но анализируем отдельно
WITH revenue_stats AS (
SELECT
AVG(total_spent) as mean_spent,
STDDEV(total_spent) as stddev_spent
FROM customers
)
SELECT
CASE
WHEN c.total_spent > (SELECT mean_spent FROM revenue_stats) + 3 * (SELECT stddev_spent FROM revenue_stats)
THEN 'VIP (Outlier)'
ELSE 'Regular'
END as customer_segment,
COUNT(*) as count,
AVG(c.total_spent) as avg_spent
FROM customers c, revenue_stats
GROUP BY customer_segment;
Пример 2: Session Duration
-- Удалить явно ошибочные сессии (> 24 часов)
-- Windsorize остальные на 95-й процентиль
SELECT
CASE
WHEN duration > 24*60 THEN NULL -- удалить очевидные ошибки
WHEN duration > PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY duration)
THEN PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY duration)
ELSE duration
END as clean_duration
FROM sessions;
Пример 3: A/B Тест с выбросами
-- Не удаляем выбросы, но делаем оба анализа:
-- Анализ 1: Все данные (robust к выбросам)
SELECT
test_group,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY metric) as median_metric
FROM ab_test
GROUP BY test_group;
-- Анализ 2: Без выбросов (для проверки)
WITH stats AS (
SELECT
AVG(metric) as mean,
STDDEV(metric) as stddev
FROM ab_test
)
SELECT
test_group,
AVG(metric) as mean_metric
FROM ab_test
WHERE metric BETWEEN (SELECT mean - 3*stddev FROM stats)
AND (SELECT mean + 3*stddev FROM stats)
GROUP BY test_group;
Как выбрать метод обработки?
1. ИССЛЕДУЙ выбросы
- Реальны ли они? (VIP клиент = не выброс)
- Ошибка данных? (удаль)
- Техсбой? (удаль или windsorize)
2. УДАЛЯЙ если:
- Явная ошибка (отрицательная цена)
- Спам/бот
- Ошибка ввода
3. ЗАМЕНЯЙ если:
- Хочешь сохранить строку
- Данные от реальных пользователей (но экстремальные)
4. ТРАНСФОРМИРУЙ если:
- Асимметричное распределение
- Логарифмическая связь в данных
5. АНАЛИЗИРУЙ ОТДЕЛЬНО если:
- Выбросы имеют смысл (VIP, специальные события)
- Нужно понять причину выбросов
Итог
Выбросы требуют внимания:
- Обнаруживай через 3-sigma, IQR или процентили
- Понимай причину выброса
- Выбирай метод в зависимости от контекста
- Документируй что делал и почему
Главное правило: Не игнорируй выбросы, разбирайся с ними!