碰撞器偏差:数据筛选如何制造虚假相关性
碰撞器是指一个变量 C,它受到两个其他变量 A 和 B 的因果影响:A → C ← B。对 C 进行条件处理——无论是通过筛选还是分层——都会在 A 和 B 之间产生虚假的相关性。
现实世界中的例子:
- 年龄 → 使用频率 → 质量(幸存下来的物品看起来质量更高)。
- 智商 → 大学录取 → 家庭财富(在学生群体中,富裕家庭的孩子似乎智力较低)。
- 天赋 → 成功 → 工作态度(成功的高天赋者显得更懒散)。
在数据科学中,这会导致误导性的模型:基于筛选后数据的梯度提升算法会继承这种偏差。
使用均匀分布数据进行模拟
我们生成 1,000 个独立点,分别从均匀分布 (0,100) 中抽取 A 和 B。当 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
散点图可视化显示,移除未存活点(蓝色)后,趋势明显向下偏移。
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}")
结果:
- 完整数据集:相关系数 ≈ 0.03
- 筛选子集:相关系数 ≈ -0.09
虽然效应较弱,但在 A/B 测试、实地研究或机器学习流程中仍具有显著影响。
如何避免分析中的碰撞器偏差
- 绘制 DAG 图:使用有向无环图在分析前识别潜在碰撞器。
- 避免基于结果的筛选:分析全人群,或采用 IPCW(逆概率删失加权)方法。
- 筛选前后检查相关性:对比不同组别间的趋势变化。
- 使用工具变量:在怀疑存在偏差时进行因果推断。
- 借助贝叶斯网络:显式建模依赖关系与条件关联。
核心要点
- 碰撞器偏差发生在对共同原因进行条件处理时,导致人为的负相关。
- 均匀分布模拟得相关系数 ≈ -0.34;正态分布模拟得 ≈ -0.09——效应强度随数据结构而变化。
- 与幸存者偏差、伯克森悖论及选择偏差密切相关。
- 数据筛选前务必绘制 DAG 图。
- 在机器学习中:筛选后的数据会导致模型偏差,造成特征重要性被低估或高估。
— Editorial Team
暂无评论。