在做机器学习建模的时候,经常遇到一个让人头疼的问题:手上有几十甚至上百个特征,到底哪些该留、哪些该丢? 科技新闻。
只做一件事:从 X 中取出 _selected 中的列,返回筛选后的 DataFrame。
比如检验 100 个特征,p=0.01 会被校正为 1.0(不再显著)。
用统背景与起因
完整的代码和模拟数据的测试用例(用统计检验筛选「体检指标」中的关键特征,预测糖尿病风险)共享在:
互信息的伪 p 值处理:
对于校正策略部分,代码中封装了 3 种校正策略:
用统事件经过
统计检验做特征选择,优点很明显:原理清晰、计算快速、结果可解释。
https://url11.ctfile.com/d/45455611-166997307-d6d609?p=6872 (访问密码: 6872)
跑之前最好先做一些基本的探索性分析。比如:
用统各方回应
[StatisticalTestSelector](file:///home/wangyubin/projects/python/python-learn/scikit-learn/特征选择/03/statistical_test_selector.py#L175-L369) 是对外暴露的主类,兼容 sklearn 的 fit / transform 接口。
所以,这里封装了_TestAdapter, 统一了调用接口,所有方法都返回 (scores, pvalues) 。
其中:
用统影响分析
实现这个基于统计显著性检验的特征选择器 ,采用了三层架构。
Benjamini-Hochberg (FDR)(最常用):
对每个特征单独做一次假设检验,看看它跟目标变量之间到底是"真有关系"还是"纯靠运气"。
就这么简单。
测试结果:
几个需要注意的区域:
本质上就是给每个特征打一个"显著性分数",然后卡个阈值做筛选。
Bonferroni 校正(最简单):
其实 sklearn 库中提供了多种统计检验方法,但它们的接口不统一:
我个人的经验:
之前两篇介绍了通过 方差阈值 和 相关性分析 来过滤特征,今天这篇介绍一种新的过滤特征的方式,也就是用统计检验来判断一个特征到底跟目标变量有没有关系。
感兴趣的朋友最好能将代码下载运行试试看,机器学习最好的理解方式就是多尝试。
p 值小于 0.05 不代表这个特征"非常重要",只是说"有统计证据表明它跟目标有关系"。在大样本情况下,即使非常微弱的关系也可能得到很小的 p 值。所以我一般会结合检验得分(比如 F 值的大小)一起看,而不是只看 p 值。
使用示例:
说白了,统计检验做特征选择的核心逻辑就一句话:
如果不做任何校正,直接用原始 p 值筛选的话,在特征少(比如十几个)的时候问题不大,但特征一旦上到几百几千,假阳性问题就很严重了。
相关文件是:statistical_test_selector.py 和 test_statistical_test_selector.py。
统计检验的思路 :
这类方法每次只看一个特征和目标变量的关系,不会考虑特征之间的交互作用。比如特征 A 单独看没用,但 A + B 组合起来可能很有用——这种情况统计检验发现不了。所以它更适合做初步筛选,后面可以再配合其他方法(比如基于树模型的特征主要性)做进一步选择。
最后画个简单的流程图,帮自己理清思路:
它不能解决所有特征选择的问题,但作为建模流程中的第一步筛选,我觉得是非常实用的,引起了广泛关注。