홈으로 돌아가기

데이터 사이언스에서의 Collider bias: 효과 시뮬레이션

이 글은 collider bias를 분석합니다 — collider로 필터링 시 상관관계 왜곡. 균등 및 정규 데이터의 Python 시뮬레이션과 시각화 제공. 분석 피하기 권장사항.

Collider bias: 데이터 필터링으로 인한 거짓 연결
Advertisement 728x90

콜라이더 편향: 데이터 필터링이 만들어내는 위조 상관관계

콜라이더는 두 변수 A와 B가 인과 관계를 통해 영향을 미치는 변수 C를 의미합니다: A → C ← B. C에 조건부로 기반하여(필터링 또는 계층화를 통해) 분석할 경우, A와 B 사이에 사실상 존재하지 않는 부정적 상관관계가 나타납니다.

실제 사례:

  • 나이 → 사용 빈도 → 품질 (생존한 제품은 더 높은 품질처럼 보임)
  • 지능 → 대학 입학 → 부모의 재산 (학생들 사이에서는 부유한 학생들이 덜 지능적으로 보임)
  • 재능 → 성공 → 노력 (성공한 재능 있는 사람들은 더 게으르게 보임)

데이터 과학에서는 이로 인해 오류가 발생하는 모델이 생성됩니다: 필터링된 데이터를 기반으로 한 그라디언트 부스팅은 편향을 그대로 물려받습니다.

Google AdInline article slot

균일한 데이터로 시뮬레이션하기

A와 B에 대해 각각 1,000개의 독립적인 점을 균일분포(0, 100)에서 생성합니다. 콜라이더 플래그는 A > 50 또는 B > 50인 경우 설정됩니다.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from statsmodels.nonparametric.smoothers_lowess import lowess

NUMBER_OF_VALUES = 1000
A_RANGE = (0, 100)
B_RANGE = (0, 100)
A_THRESHOLD = 50
B_THRESHOLD = 50

a = np.random.uniform(*A_RANGE, NUMBER_OF_VALUES)
b = np.random.uniform(*B_RANGE, NUMBER_OF_VALUES)
data = pd.DataFrame({'a': a, 'b': b})
data['flag'] = (data['a'] > A_THRESHOLD) | (data['b'] > B_THRESHOLD)
print(f"A와 B 간 상관관계: {data['a'].corr(data['b']):.2f}")
print(f"플래그가 참인 경우의 상관관계: {data[data['flag']]['a'].corr(data[data['flag']]['b']):.2f}")

결과:

  • 전체 데이터셋: 상관관계 ≈ 0.00
  • 필터링된 부분집합: 상관관계 ≈ -0.34

산점도 시각화는 비생존 항목(파란색)을 제거함으로써 추세가 하향되는 방식을 보여줍니다.

Google AdInline article slot
sns.scatterplot(data=data, x='a', y='b', hue='flag', palette={True: 'red', False: 'blue'}, alpha=0.5)
sns.regplot(data=data, x='a', y='b', scatter=False, color='black')
plt.show()

필터링 후 lmplot는 음의 기울기를 보입니다. 우상단 사분면이 비어있어 균형이 무너집니다.

현실적인 시나리오: 정규분포 사용

이제 np.random.normal을 사용해 A ~ N(50,5), B ~ N(30,5)로 설정합니다. 콜라이더는 확률적입니다: 값을 정규화하고, 선택 확률을 max(a_norm, b_norm)*1.5로 계산한 후 [0,1] 범위로 클리핑한 후, 임의 추출을 통해 플래그를 할당합니다.

a = np.random.normal(loc=50, scale=5, size=NUMBER_OF_VALUES)
b = np.random.normal(loc=30, scale=5, size=NUMBER_OF_VALUES)
normal_data = pd.DataFrame({'a': a, 'b': b})
a_norm = (normal_data['a'] - normal_data['a'].min()) / (normal_data['a'].max() - normal_data['a'].min() + 1e-6)
b_norm = (normal_data['b'] - normal_data['b'].min()) / (normal_data['b'].max() - normal_data['b'].min() + 1e-6)
selection_prob = np.maximum(a_norm, b_norm) * 1.5
selection_prob = np.clip(selection_prob, 0, 1)
normal_data['flag'] = np.random.random(len(normal_data)) < selection_prob
print(f"전체 데이터셋의 상관관계: {normal_data['a'].corr(normal_data['b']):.2f}")
print(f"플래그가 참인 경우의 상관관계: {normal_data[normal_data['flag']]['a'].corr(normal_data[normal_data['flag']]['b']):.2f}")

결과:

Google AdInline article slot
  • 전체 데이터셋: 상관관계 ≈ 0.03
  • 필터링된 부분집합: 상관관계 ≈ -0.09

효과는 약하지만, A/B 테스트, 현장 연구, 머신러닝 파이프라인에서는 여전히 의미 있게 나타납니다.

분석에서 콜라이더 편향 피하기 방법

  • DAG 그리기: 분석 전에 방향성 없는 순환 그래프(DAG)를 그려 콜라이더를 식별하세요.
  • 결과 기반 필터링 피하기: 전체 인구집단을 분석하거나 IPCW(역확률 검열 가중치)를 적용하세요.
  • 계층화 전후 상관관계 확인: 그룹 간 추세를 비교하세요.
  • 도구변수 활용: 편향이 의심될 경우 인과 추론에 도구변수를 사용하세요.
  • 베이지안 네트워크 활용: 종속성과 조건부 관계를 명시적으로 모델링하세요.

핵심 요약

  • 콜라이더 편향은 공통 원인이 조건부로 고려될 때 인위적인 음의 상관관계를 유발합니다.
  • 균일 데이터 시뮬레이션에서는 상관관계 ≈ -0.34, 정규 데이터에서는 ≈ -0.09 — 효과는 데이터 구조에 따라 달라집니다.
  • 생존 편향, 버크슨 역설, 선택 편향과 관련이 있습니다.
  • 항상 데이터 필터링 전에 DAG를 그려보세요.
  • 머신러닝에서는 필터링된 데이터가 편향된 모델을 만들며, 특성 중요도를 과소 또는 과대평가하게 됩니다.

— Editorial Team

Advertisement 728x90

다음 읽기