Что такое selection bias и как он влияет на данные?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
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?
- Правильный sampling: Случайная выборка, stratified sampling для подгрупп
- Полнота данных: Минимизировать пропуски и censoring
- Взвешивание: IPW (Inverse Probability Weighting) для компенсации
- Causal inference: Использовать методы причинного анализа (propensity score matching)
- Внешняя валидация: Тестировать на независимом датасете от другого источника
- Мониторинг дрейфа: Постоянно сравнивать distribution training/production данных
На практике
Selection bias — главный враг reproducibility. Модель, которая отлично работает на обучении, может провалиться в production именно из-за скрытого смещения в данных. Правильное осознание этой проблемы и её систематический поиск — ключ к надёжным ML системам.