Python如何识别CSV数据表中变量间的依赖关系
为什么corr()识别不出这类依赖
pandas默认的df.corr()计算的是皮尔逊线性相关系数,仅能捕捉变量间的线性共变关系。这类依赖属于「触发式阶跃依赖」:i1变为True是状态开关,触发后m1跳转到固定值且不再变化,二者不存在线性同增同减的关系,因此相关系数极低是正常结果。另外示例代码里的sns.heatmpa存在拼写错误,正确写法是sns.heatmap,但该问题不影响相关系数的计算逻辑。
Python下识别这类依赖的可行方法
以下方法都适配非线性、触发式的字段依赖关系,适配千行规模的数据集:
时序触发规则校验
数据带有序ID,是典型的时序观测数据,可直接定位布尔字段的跳变点,校验跳变前后目标字段的取值约束:import pandas as pd # 字段类型转换 dat['i1'] = dat['i1'].astype(bool) dat['i2'] = dat['i2'].astype(bool) dat['m1'] = pd.to_numeric(dat['m1']) # 定位i1首次跳变为True的位置 trigger_pos = dat.loc[dat['i1'] == True, 'id'].min() if not pd.isna(trigger_pos): pre_vals = dat.loc[dat['id'] < trigger_pos, 'm1'].unique() post_vals = dat.loc[dat['id'] >= trigger_pos, 'm1'].unique() # 校验跳变后取值是否唯一且和跳变前无重叠 if len(post_vals) == 1 and post_vals[0] not in pre_vals: print(f"检测到强依赖:i1首次为True后,m1固定取值为{post_vals[0]}")互信息计算
互信息衡量的是两个变量共享的信息量大小,对非线性、阶跃类的关联非常敏感,取值范围为[0, +∞),值越大说明依赖越强。可使用scikit-learn的内置接口计算:from sklearn.feature_selection import mutual_info_regression # 布尔字段转0/1数值,标记为离散特征 X = dat[['i1', 'i2']].astype(int) y = dat['m1'] mi_scores = mutual_info_regression( X, y, discrete_features=[True, True], # 标记输入特征都是离散值 random_state=42 ) print(pd.Series(mi_scores, index=X.columns).sort_values(ascending=False))这类场景下
i1和m1的互信息得分会显著高于无关字段,可直接识别出关联。浅决策树规则提取
训练最大深度2-3层的浅决策树预测目标字段,既可以通过特征重要性排序找到对目标影响最大的字段,还可以直接输出可解释的规则,匹配「某字段取某值后另一字段固定」的依赖模式:from sklearn.tree import DecisionTreeRegressor, export_text tree = DecisionTreeRegressor(max_depth=3, random_state=42) tree.fit(X, y) # 输出特征重要性 print("特征重要性:\n", pd.Series(tree.feature_importances_, index=X.columns).sort_values(ascending=False)) # 输出拆分规则 print("\n字段依赖规则:") print(export_text(tree, feature_names=list(X.columns)))针对给出的样例数据,模型会直接输出
|--- i1 <= 0.50 -> 取值0.0、|--- i1 > 0.50 -> 取值80.0的明确规则。条件取值一致性校验
遍历所有字段的取值组合,统计当字段A取固定值时,字段B的取值唯一率:如果A取某个值时,B的取值100%为固定常量,就说明二者存在强确定性依赖。该方法适合查找硬依赖,不会漏过任何确定性的取值约束。
内容的提问来源于stack exchange,提问作者NotYourFan

