如何理解 ANOVA-F 在 Python 中进行特征选择。Sklearn SelectKBest 与 f_classif
数据挖掘
分类
特征选择
2021-10-12 10:05:55
2个回答
直觉
我们有两个类别,我们想为每个特征找到一个分数,说明“这个特征在两个类别之间的区分程度”。现在看下图。有红色和蓝色两个类和两个特征 和 轴。
特征是一个更好的分隔符 因为如果我们将数据投影在 轴我们得到两个完全分离的类,但如果我们将数据投影到 ,两个类在轴的中间有重叠(如果我们需要更多说明,请评论)。
是什么使得 好于 ? 如上图所示:
- 根据,两个班相距甚远。
- 数学翻译:类分布均值之间的距离超过.
- 根据, 类的散布点不是相互重叠而是根据他们是这样。这意味着根据,类更紧凑,因此更有可能与另一个类不重叠。
- 数学翻译:每个单类的方差根据小于那些.
现在我们可以很容易地说是个好成绩!这个分数越高,特征区分类别的能力就越好。
现在我们知道,根据这个定义,什么 和 特征的意思。让我们找到一个数学公式来量化它。
数学(在纸上做)
让我们制定我们的两个标准:
- 类分布均值之间的距离是分子。考虑到人口,我假设具有统计意义(需要统计学家的参考!)。
- 一个类似于类样本方差的概念是分母。这里不是将平方和除以, 我们总结所有s 并将最终值除以它们。
现在回到您的数据
要计算上述内容,您可以根据不同的类计算每个特征的类间距离总和和类内变化总和。我只为一个功能做这件事。让我们选择贷款。
Class 1: [5000, 18000]
Class 2: [47500, 45600, 49500]
Mean of all points: (47500 + 45600 + 49500 + 5000 + 18000) / 5 = 33120
Mean 1: (5000 + 18000) / 2 = 11500
Mean 2: (47500 + 45600 + 49500) / 3 = 47533
Numerator: 2 x (11500 - 33120)^2 + 3 x (47533 - 33120)^2 = 1,558,052,507
对于分母,我们使用类内的平方和(它只是样本方差公式中的分子):
SSW 1: (5000 - 11500)^2 + (18000 - 11500)^2 = 84,500,000
SSW 2: (47500 - 47533)^2 + (45600 - 47533)^2 + (49500 - 47533)^2 = 7,606,667
Na = 2, Nb = 3 --> (Na - 1) + (Nb - 1) = 1 + 2 = 3
Denominator: (84,500,000 + 7,606,667)/3 = 30,702,222
现在特征贷款的 F 分数是:
F-Score: 1,558,052,507 / 30,702,222 = 50.74
正如您在 Python 中的计算所见。
笔记
- 我试图用一种简单的方式来解释。例如,样本方差的分母称为自由度,但为简单起见,我跳过了这些术语。
- 只要理解主要思想。进一步的均值和较小的内方差,更好的特征。您也可以自己制定它(但是您将不再有 p 值;))
- 找到 P 值并理解它的含义是我跳过的另一个故事。
希望它有所帮助。祝你好运!
f_classif 计算的 F-score 可以使用图像中显示的以下公式手动计算:参考视频
直观地说,它是(输入特征(X)解释的输出特征(y)的方差与输入特征(X)未解释的输出特征(y)的方差)的比率。
例子 :
使用 f_classif 的 sklearn 代码
from sklearn.feature_selection import f_classif
import numpy as np
X = np.array([5000, 18000, 47500, 45600, 49500]).reshape(-1,1)
y = np.array([1,1,0,0,0])
F,pval = f_classif(X,y)
print(F,pval)
[50.74816155] [0.00569324]
使用上述公式验证
X = np.array([5000, 18000, 47500, 45600, 49500])
X1 = np.array([5000, 18000])
X2 = np.array([47500, 45600, 49500])
mu = np.mean(X) # overall mean
mu1 = np.mean(X1) # mean of X1
mu2 = np.mean(X2). # mean of X2
SSm = np.sum(((X-mu)**2)) # SS(mean)
SSf = np.sum((X1-mu1)**2) + np.sum((X2-mu2)**2) # SS(fit)
p_fit = 2
p_mean = 1
F = ((SSm - SSf)*(X.shape[0]-p_fit))/((p_fit - p_mean)*SSf)
print(F)
50.74
其它你可能感兴趣的问题