Python实现多ML分类器与数据集重采样配对t检验异常排查
多分类器多数据集场景下配对t检验异常原因说明
准确率结果每次运行不一致的核心原因
- 分类器实例状态污染:嵌套循环中直接引用
clf_list内的分类器对象、未执行深拷贝是核心诱因。Sklearn分类器调用fit()方法会直接覆盖实例内存储的模型参数,多轮循环下同一个分类器实例会被反复拟合,上一轮训练的参数残留、内部随机状态会直接干扰下一轮结果。单组两两对比时每次都是独立初始化/拟合分类器,不会触发该问题。 - 随机数控制逻辑失效:原双分类器代码在循环外固定了随机数生成器,按固定顺序生成数据拆分的随机种子,结果可复现。加入多层分类器循环、多数据集读取逻辑后,如果随机数生成器初始化位置错误、没有同步固定所有数据拆分、模型内部随机过程的种子顺序,不同轮次消耗随机数的顺序发生变化,数据拆分结果、模型随机采样(如随机森林的特征/样本采样)结果都会出现波动,最终准确率每次运行都不一致。
出现大于1的无效p值的核心原因
- p值计算逻辑存在边界漏洞:原代码中
p_value = t_dist.sf(t, n-1)*2的写法仅在t统计量为正时有效。t分布的生存函数sf()返回的是统计量大于观测值的右尾概率,当t统计量为负时,右尾概率会大于0.5,直接乘2就会得到大于1的无效值。双分类器对比时模型顺序固定,准确率差值均值始终为正,不会触发该边界;多分类器两两对比时必然出现第二个分类器准确率高于第一个的情况,此时t统计量为负,就会算出无效p值。修正方式为计算时取t统计量的绝对值:p_value = t_dist.sf(abs(t), n-1)*2,也可以直接调用统计库的双边检验接口避免手动计算出错。 - 差值数组未按轮次重置:当前代码中
p_数组在循环外初始化,如果不同分类器对、不同数据集的循环之间没有清空重置数组,会残留上一轮计算的准确率差值,导致t统计量计算基于错误的输入序列,也可能输出异常p值。
补充提示:多组分类器两两对比时,重复执行配对t检验会放大家族一类错误率,建议后续搭配Bonferroni或Holm校正方法调整p值,提升显著性判断的可靠性。
内容的提问来源于stack exchange,提问作者dododabird
相关产品推荐
相关产品推荐

