← Назад к вопросам

Что такое selection bias и как он влияет на данные?

2.0 Middle🔥 182 комментариев
#Статистика и A/B тестирование

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Selection Bias и его влияние на данные

Selection bias (смещение отбора) — одна из самых коварных проблем в машинном обучении и статистике. Это систематическое искажение данных, когда выборка не репрезентирует всю генеральную совокупность из-за способа отбора.

Определение и типы

Selection bias возникает, когда вероятность попадания элемента в выборку зависит от значения целевой переменной или от характеристик, коррелирующих с ней.

Основные типы selection bias

1. Sampling Bias (Смещение выборки)

Возникает при неправильном способе сбора данных. Не все элементы генеральной совокупности имеют равный шанс быть выбранными.

# Пример: опрос по телефону
# Смещение: люди с телефонами != все люди
# Смещение: люди, готовые разговаривать, отличаются от тех, кто не готов

# Неправильный способ:
responders = online_survey_data  # только люди, пользующиеся интернетом

# Проблема: пожилые люди недопредставлены
# Вывод о популярности соц. сетей будет завышен

2. Censoring и Truncation

Censoring — когда мы знаем, что значение существует, но не знаем его точно.

# Пример: время до события (хирургический успех)
# Если пациент жив на конец исследования, время "censored"

import pandas as pd
import numpy as np

# Генерируем данные
time_to_event = np.array([3, 5, 8, 10, 12, 15])  # дни
censored = np.array([0, 0, 1, 0, 1, 1])  # 1 = события не было в конце

df = pd.DataFrame({
    'time': time_to_event,
    'event': 1 - censored,
    'censored': censored
})

# Неправильный расчёт (игнорируем censoring):
mean_time = df[df['event'] == 1]['time'].mean()  # Занижена!

# Правильный подход: Kaplan-Meier estimator
from lifelines import KaplanMeierFitter

kmf = KaplanMeierFitter()
kmf.fit(df['time'], df['event'])
kmf.plot_survival_function()

Truncation — когда мы видим только часть данных.

# Пример: зарплаты, только у людей зарабатывающих > 50k
# Мы никогда не видим людей с зарплатой < 50k
data_truncated = all_salaries[all_salaries > 50000]
# Среднее значение сильно завышено!

3. Survivorship Bias

Мы видим только "выживших", забывая о тех, кто выбыл из наблюдения.

# Классический пример: анализ возвращения компаний
# 1990-е: анализируем компании, которые выжили до 2020
# Забываем о тех, кто разорился и удален из данных

# Результат: средний ROI завышен, риск занижен

# Статистика выжившие компаний → неправильный вывод о рынке
survivors = stock_data[stock_data['exists_in_2020'] == True]
mean_return = survivors['return'].mean()  # Смещено!

4. Collider Bias (Смещение коллайдера)

Окондирование на переменную, которая зависит от двух независимых факторов, создаёт ложную корреляцию.

# Пример: способность и трудолюбие в найме
# Способность → зарплата (независимые переменные)
# Трудолюбие → зарплата

# Если анализируем только нанятых людей (сортировка по зарплате),
# между способностью и трудолюбием появляется ОТРИЦАТЕЛЬНАЯ корреляция!
# Парадокс: способные люди могут быть ленивыми и всё равно наняты

import numpy as np
np.random.seed(42)

# Генерируем независимые переменные
ability = np.random.normal(0, 1, 1000)
hard_work = np.random.normal(0, 1, 1000)

# Зарплата зависит от обоих
salary = ability + hard_work + np.random.normal(0, 0.5, 1000)

# Анализ всех людей
corr_all = np.corrcoef(ability, hard_work)[0, 1]  # ~0 (не коррелируют)

# Анализ только нанятых (зарплата > median)
hired_mask = salary > np.median(salary)
corr_hired = np.corrcoef(ability[hired_mask], hard_work[hired_mask])[0, 1]  # < 0!

print(f'Корреляция в полной выборке: {corr_all:.3f}')
print(f'Корреляция в выборке нанятых: {corr_hired:.3f}')

5. Non-Response Bias

Люди, не ответившие на опрос, отличаются от тех, кто ответил.

# Пример: опрос удовлетворённости клиентов
# Недовольные люди с меньшей вероятностью ответят
# Результат: средний рейтинг завышен

# Решение: увеличить rate of response, использовать взвешивание
response_rate = len(responses) / len(invited)  # обычно 20-30%

# Взвешивание по вероятности отклика
weights = 1 / response_probability_by_group
weighted_mean = np.average(ratings, weights=weights)

Как selection bias влияет на модели ML?

Проблема 1: Смещение предсказаний

# Обучили модель на смещённых данных
model.fit(X_biased, y_biased)

# На реальных данных модель ошибается систематически
y_pred = model.predict(X_real)
print(f'Средняя ошибка: {(y_pred - y_real).mean()}')
# Результат: не 0, а заметное смещение!

Проблема 2: Завышенная оценка качества

# Обучали на смещённых данных
# Тестировали на другом наборе из той же смещённой совокупности

accuracy_train = model.score(X_train_biased, y_train_biased)  # 95%
accuracy_test = model.score(X_test_biased, y_test_biased)      # 93%

# На реальных несмещённых данных:
accuracy_real = model.score(X_real, y_real)  # 65% 😱

Проблема 3: Неправильные feature importance

# В смещённых данных может быть false positive correlation
# Модель изучает артефакты смещения, а не реальные паттерны

feature_importance = model.feature_importances_
# feature_X имеет высокую важность только из-за смещения!

Как обнаружить selection bias?

# 1. Сравнить распределение в выборке с известным распределением в популяции
from scipy import stats

train_age_mean = X_train['age'].mean()
population_age_mean = 45  # известное значение

if abs(train_age_mean - population_age_mean) > threshold:
    print("Вероятен selection bias по возрасту!")

# 2. Анализ missing data
missing_per_feature = X.isnull().sum() / len(X)
if missing_per_feature.max() > 0.05:
    print("Потенциальный MCAR/MNAR bias")

# 3. Сравнить distribution train/test на реальных данных
import matplotlib.pyplot as plt

plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.hist(X_train['feature'], bins=30, alpha=0.5, label='Train')
plt.hist(X_test['feature'], bins=30, alpha=0.5, label='Test')
plt.legend()
plt.title('Проверка на дрейф')

plt.subplot(1, 2, 2)
plt.hist(X_train['feature'], bins=30, alpha=0.5, label='Train')
plt.hist(X_real['feature'], bins=30, alpha=0.5, label='Real')
plt.legend()
plt.title('Проверка на bias к реальности')
plt.show()

Как минимизировать selection bias?

  1. Правильный sampling: Случайная выборка, stratified sampling для подгрупп
  2. Полнота данных: Минимизировать пропуски и censoring
  3. Взвешивание: IPW (Inverse Probability Weighting) для компенсации
  4. Causal inference: Использовать методы причинного анализа (propensity score matching)
  5. Внешняя валидация: Тестировать на независимом датасете от другого источника
  6. Мониторинг дрейфа: Постоянно сравнивать distribution training/production данных

На практике

Selection bias — главный враг reproducibility. Модель, которая отлично работает на обучении, может провалиться в production именно из-за скрытого смещения в данных. Правильное осознание этой проблемы и её систематический поиск — ключ к надёжным ML системам.

Что такое selection bias и как он влияет на данные? | PrepBro