这两天在看Sklearn的文档,在feature_selection一节中遇到俩f值,它们是用来判断模型中特征与因变量的相关性的。刚开始看的时候一头雾水,因为需要数理统计中方差分析的背景,现在在这里简要剖析一下这两个方法的原理和用法。
我们先来看看sklearn的API是怎么解释这两个方法的:
Compute the ANOVA F-value for the provided sample. ——sklearn.feature_selection.f_classif
f_calssif计算ANOVA中的 f 值,这和特征选择怎么搭上关系???
下面是对f_regression的解释,更晕了。。
Univariate linear regression tests.
Linear model for testing the individual effect of each of many regressors. This is a scoring function to be used in a feature seletion procedure, not a free standing feature selection procedure.
This is done in 2 steps:
The correlation between each regressor and the target is computed, that is,
((X[:, i] - mean(X[:, i])) * (y - mean_y)) / (std(X[:, i]) * std(y)).
It is converted to an F score then to a p-value.
——sklearn.feature_selection.f_regression
在传统的统计学中 f 值是用于方差分析的(analysis of variance),感兴趣的旁友可以参考任意一本统计学教材,里面有关于方差分析的详细推导和流程,我在这里就做一下简单的引入。传统的方差分析(或者说是多重均值比较)是这样的,举个经典的栗子:
我们开发出了一种降血压的药,需要检验这个降血压药品的药效如何。我们就做了如下实验,给定不同剂量,分别是0,1,2,3,4这四个级别的剂量(0剂量表示病人服用了安慰剂),给4组病人服用,在一定时间后测量病人的血压差,在得到数据以后。我们要问,这种新药是不是有显著药效,也就是说病人的血压差是不是显著的不等于0。
数据如下:
剂量 | 血压差 |
---|---|
0 | x01 x02 … x0n0 |
1 | x11 x12 … x1n1 |
2 | x21 x22 … x2n2 |
3 | x31 x32 … x3n3 |
4 | x41 x42 … x4n4 |
我们得到了5个总体 Xi,i=0,1,2,3,4 ,这五个总体的均值为 μi ,我们假设是:
H0:μ0=μ1=μ2=μ3=μ4=0
H1:μi中至少有一个不为0
继而构造检验统计量 f=SA/(r−1)SE/(n−r) , SA,SE 分别是组间和组内离差,这个统计量服从 F(r−1,n−r) ,式中 n=∑ini ,也就是总样本数, r 是总体个数。在我们这个例子中, r=5,n=n0+n1+n2+n3+n4 ,那么这个统计量 f 服从分布 F(4,n−5) 。当这个统计量比较大的时候,也就是超过 F1−α(4,n−5) 时,我们拒绝零假设,即认为几个 μi 中至少有一个不为0,即认为新药有显著的改变血压。
举这个例子是为了说明 f 值这个统计量最初的目的,在这个例子中,是为了检验:在不同的药剂量下,血压差是不是有显著的差异。那么我们再抽象一下,方差分析的目的是:在随机变量 Y 的不同水平下,检验某个变量 X 是不是有显著的变化。
ps:你似乎可以隐隐的感受到,这似乎是在说变量 X 和 Y 之间的相关性???
前面做了那么多铺垫,终于进入正题了。前面提到利用 f 值这个检验统计量,可以判断假设 H0 是否成立: f 值越大,大到一定程度时,就有理由拒绝零假设,认为不同总体下的均值存在显著差异。
那么在机器学习的分类问题中,怎么理解呢?
我们可以把样本所属的不同的类别视作不同的总体,假设是个二分类问题,我们要考虑特征 xi 。那么,如果 xi 这个特征对预测类别很大的帮助,它必然存在这样一种特征:
当样本 x 属于正类时, xi 会取某些特定的值(视作集合 S+ ),当样本 x 属于负类时, xi 会取另一些特定的值( S− )。
我们当然希望集合 S+ 与 S− 呈现出巨大差异,这样特征 xi 对类别的预测能力就越强。落实到刚才的方差分析问题上,就变成了我们需要检验假设 H0:μS+=μS− ,我们当然希望拒绝 H0 ,所以我们希望构造出来的 f 值越大越好。也就是说 f 值越大,我们拒绝 H0 的把握也越大,我们越有理由相信 μS+≠μS− ,越有把握认为集合 S+ 与 S− 呈现出巨大差异,也就说 xi 这个特征对预测类别的帮助也越大!
所以我们可以根据样本的某个特征 xi 的 f 值来判断特征 xi 对预测类别的帮助, f 值越大,预测能力也就越强,相关性就越大,从而基于此可以进行特征选择。
另外,我们也可以利用f_calssif方法来计算两个特征之间的相关性,前提是其中一个变量是离散型的类别变量。
前面讲了在分类问题中的 f 值怎么计算,结合方差分析相信能理解其原理。
那么回归问题中,怎么算 f 值?前面说到一个类别对应一个总体,回归问题中的因变量是连续值,这该怎么办?
我们参照sklearn官方给的公式:
ri=(X[:,i]−mean(X[:,i])(y−mean(y))std(X[:,i])std(y)
似曾相识的感觉,我们把它写的规范一点,是这样的:
ri=(Xi−X¯i)T(y−y¯)std(Xi)std(y)
式中 Xi 是代表所有样本的在i号特征上的取值的 n 维列向量,分子上其实两个 n 维列向量的内积,所以 ri 是一个数值,其实就是样本相关系数。
那么这个我们一直在讨论的 f 值从哪来,原文中说”It is converted to an F score then to a p-value”,怎么个convert法?其实 f=r2i1−r2i∗(n−2) ,如果 Xi,y 都服从正态分布的话,这个 f 服从 F(1,n−2) 。如果我们对 f 开方,它就服从 t(n−2) 分布。
学过统计的旁友可能还会记得,我们常用 t=n−2‾‾‾‾‾√ri1−r2i√ 这个统计量来检验正态假定下两个变量之间的相关性(有兴趣的旁友可以参考任意一本多元统计分析的教材)。
如果你还是有点迷糊,我们再来总结一下:
要计算f_regression中的 f 值,我们首先要计算的是 ri=(X[:,i]−mean(X[:,i])(y−mean(y))std(X[:,i])std(y) ,这个就是i号特征和因变量y之间的样本相关系数。
我们计算的 f=r2i1−r2i∗(n−2) ,才是f_regression中的 f 值,服从 F(1,n−2) 分布。
f 值越大,i号特征和因变量y之间的相关性就越大,据此我们做特征选择。
如果你参考了这两个方法的API,会看到这个方法返回两个变量,一个是 f 值,还有一个是pvalue,这个pvalue就是用于检验特征与变量之间相关性的,假设你给出 α 值(常常取0.05,0.01),如果你的pvalue小于 α ,那就有把握认为,这个特征和预测变量y之间,具有相关性。比方说你取 α =0.05,这就意味着你有95%(也就是1- α )的把握认为,这个特征和预测变量y之间存在相关性。
其实你可以看到,Sklearn中的f_classif和f_regression基于的原理是有所差异的,前者是基于方差分析的检验统计量 f 值,后者其实是基于样本相关系数的检验,理论上我们可以用一个t检验来代替,但sklearn还是把它转换成了一个 f 值,想必他有自己的考量。
如果看了这篇文章你还闹不清的话,请记住 f 值和相关性之间的千丝万缕的联系, f 值越大,那么特征对因变量 y 的预测能力就越强,就越重要!