数据预处理和特征工程 - 特征选择 - 相关性过滤 - 互信息法 & F 检验
互信息法
不想追究这个原理了,以后补上
互信息法是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法。和 F 检验相似,它既可以做回归也可以做分类,并且包含两个类 feature_selection.mutual_info_classif(互信息分类)和 feature_selection.mutual_info_regression(互信息回归)。这两个类的用法和参数都和 F 检验一模一样,不过互信息法比 F 检验更加强大,F 检验只能够找出线性关系,而互信息法可以找出任意关系。
互信息法不返回 p 值或 F 值类似的统计量,它返回“每个特征与目标之间的互信息量的估计”,这个估计量在之间取值,为 0 则表示两个变量独立,为 1 则表示两个变量完全相关。以互信息分类为例的代码如下:
过滤法总结
建议先使用方差过滤,然后使用互信息法来捕捉相关性
等我踩了坑再来补吧,不清楚为什么 F 检验要求数据服从正态分布
F 检验
前置知识比较多,慢慢说
z 分布
对于,有
t 分布
t 分布的公式推导
其中对于
因此,对于,则有
自由度越高,t 分布越接近于标准正态分布
F 分布
F 分布主要是用来分析多总体均值的比较,对于两个总体均值的比较,我们一般用 t 检验,即
三个及三个以上总体均值的比较我们一般用 F 检验,F 直观的形式为
与 t 检验相同的部分,我们的假设
F 值的求法:
把 n 组数据放在一起,看成一个总体,算出这个总体的均值
计算出每组数据的组内平均值
计算出组间差异
$n_{i}i$组数据的数量
计算出组内差异
$$
$$
表示组数量,表示数据个数
视频作者:林泰峰老师的个人空间_哔哩哔哩_bilibili链接:十分钟理解t分布和t检验_哔哩哔哩_bilibili十五分钟理解F分布和方差分析_哔哩哔哩_bilibili
对于一个检验,我们的零假设应该是
$$这里对于不同标签的取值,不同特征的分布有差异,改为另一个种表述,即特征与标签是显著线性相关的
之前我们已知
这里表示标签的种类数,表示样本数量
这里我们强调一下 SST、SSE、SSW 假设目前有条数据被分成组(即标签有个类别),其中第个类别中包含条样本,并且表示第个类别的第条样本样本整体偏差 SST
组内偏差平方和 SSE
组间偏差平方和 SSB
在总体偏差不变的情况下(给定一组数据,就会有一个固定的 SST),我们希望组内偏差越小越好、而组间偏差越大越好,因为这样就能证明组内数据彼此更加相似、而不同分组的数据彼此会更加不同。同样的观点也适用于当前情况,即在给定一个离散变量和连续变量的时候,我们就可以利用离散变量的不同取值对连续变量进行分组(例如根据是否流失,划分为流失用户组和非流失用户组),此时 SST 是一个确定的值,并且如果 SSB 很大、SSE 很小,则说明不同组的组间差异越大、组内差异较小,而所谓的组间差异,其实也就是由均值的不同导致的,SSB 越大则不同组的均值都和整体均值差异较大,并且由于此时 SSE 很小,也就说明每个组内的取值和该组的均值比较接近,此时我们会更倾向于判断不同组是取自不同总体;而反之,如果 SSB 很小而 SSE 很大,则倾向于判断不同组是取自同一个总体。
numpy 实现 f_classif,有助于理解
import numpy as np X = np.array([[3.4, 3.4, 3. , 2.8, 2.7, 2.9, 3.3, 3. , 3.8, 2.5],[9, 9, 9, 1, 1, 1, 11, 15, 15, 15]]) y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2, 2]) df = pd.concat([pd.Series(y),pd.DataFrame(X).T],axis=1) df.columns = ['y','x0','x1'] x = df.columns[1] # 在这改列号就可以计算x1列的F X0 = df.loc[df.iloc[:,0]==0,x] X1 = df.loc[df.iloc[:,0]==1,x] X2 = df.loc[df.iloc[:,0]==2,x] SSE0 = np.power(X0 - X0.mean(),2).sum() SSE1 = np.power(X1 - X1.mean(),2).sum() SSE2 = np.power(X2 - X2.mean(),2).sum() SSE = SSE1 + SSE2 + SSE0 SSE --- 1.0166666666666662 X_mean = (X0.sum() + X1.sum() + X2.sum())/10 SSB = X0.shape[0] * np.power(X0.mean() - X_mean,2)+ X1.shape[0] * np.power(X1.mean() - X_mean,2)+ X2.shape[0] * np.power(X2.mean() - X_mean,2) SSB --- 0.3593333333333332 F = (SSB/2)/(SSE/(10-3)) F --- 1.2370491803278691 # 如果df.columns[2],此处为84.7 # 对应的sklearn from sklearn.feature_selection import f_classif F , pf = f_classif(X.T,y) F,pf --- (array([ 1.23704918, 84.7 ]), array([3.46705337e-01, 1.24479578e-05]))
对于 f_classif,我们判断的只是不同类别标签对应的特征是否取自同一总体,用于标签是离散型变量的数据;而 f_regression 是检验变量与标签的线性关系,回归用于标签是连续型变量的数据
需要注意的是,f_regression 计算 F 的方式和 f_classif 是不同的,其实也很好理解,前者需要判断线性关系,后者只需要判断相关性
sklearn 中 f_regression 构建了一个如下形式的 F 统计量:
其中为两个连续变量的相关系数,并且满足自由度为的 F 分布。该计算过程并不复杂,并且统计量 F 和变化方向一致,即与相关系数绝对值的变化保持一致,本质上和相关系数一样,也是衡量了两个变量之间的相关性,并且是一种线性相关关系,并且数值越大、线性相关关系越强,反之则越弱。这些都不难理解,但问题是为什么会服从 F 分布呢?这里我们需要先回顾下的计算公式,相关系数的计算公式是用 xy 的协方差除以 x 的标准差和 y 的标准差之积:
相关系数的另一种解释方法是相互解释的变异占变异的比例。同离散变量的方差分析类似,定义总变差(Total variation)为 SST:
而已经解释的变差(Explained variation)为 SSR:
则有
类似的,未解释的变差部分我们也可以用 SSE 来进行表示,即 SSE=SST-SSR。这里需要注意,如果这里不是 x 和 y,而是 y 的预测值和 y 的真实值,则决定系数。这也是为何经常会说决定系数实际上就是相关系数的平方的结论。此时我们再看所代表的含义,就非常清楚了:
已解释的变差和未解释的变差比例,而(n-2)实际上就是自由度,即:
相当于是对统计量的修正,而最终一旦找到了检验统计变量,我们就可以推断当前事件发生的概率,进而有理有据的接受或者拒绝零假设。而这里的基于相关系数的检验,零假设是二者不存在线性相关关系。由于最终的检验统计变量仍然是服从 F 分布的,因此我们称其为线性相关性的 F 检验。并且,此时假设检验中零假设与备择假设如下:
该方法的缺点是只能检测线性相关关系,但不相关不代表独立,可能是非线性相关关系。
作者:cy^2链接:3、特征选择(filter):线性相关性的F检验_cy^2的博客-CSDN博客_特征选择f检验
其实这里我没看懂,先贴在这,回头再说
视频作者:菜菜TsaiTsai链接:【技术干货】菜菜的机器学习sklearn【全85集】Python进阶_哔哩哔哩_bilibili
版权声明: 本文为 InfoQ 作者【烧灯续昼2002】的原创文章。
原文链接:【http://xie.infoq.cn/article/3274775c08fb48a9ca12f129f】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论