特征选择系列:
特征选择方法详解Part1-方差分析、Pearson、Spearman
特征选择方法详解Part2-卡方检验、互信息(Mutual Information)
特征选择方法详解Part3-SelectFromModel-RFE、L1、Tree、Permutation importance
正常的机器学习项目,除了数据清洗,特征工程是最耗时和耗精力的步骤,也是对整个项目效果好坏起决定性作用的步骤之一。特征工程更多的是经验性的东西,当然所有的经验都建立在对基本方法的了解之上。本文将对特征工程中特征选择的常用方法方差分析、Pearson、Spearman进行介绍。
文章同步发在我的个人博客,欢迎大佬们指教。特征选择方法详解Part1-方差分析、Pearson、Spearman
此种方法是最基本、最简单也是最重要的一步。
当数据准备好,几百个特征摆在眼前,如果我们对业务很熟悉,有比较深刻的理解,我们自然能知道哪些特征很重要,而哪些特征没什么用,这样就自然而然的去掉了一些特征,再继续使用其他方法进行特征选择。
而当我们对业务不太熟悉,或者没办法短时间内有很深刻的理解。比如说一个纯技术的同学,突然接到一个关于医疗的项目,我想最聪明的办法,去找医生聊一聊,让他们给一些建议。
方差分析是一个简单、基本的特征选择方法。简单来说,方差越大的特征,认为其越有用,而方差越小的特征,因为每个样本在此特征的值比较接近或者相同,就认为其对模型训练没有作用。sklearn中的方法VarianceThreshold可以很方便的完成此项工作。这里直接给出官方文档中的示例:
>>> from sklearn.feature_selection import VarianceThreshold
>>> X = [[0, 0, 1],
[0, 1, 0],
[1, 0, 0],
[0, 1, 1],
[0, 1, 0],
[0, 1, 1]]
>>> sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
>>> sel.fit_transform(X)
array([[0, 1],
[1, 0],
[0, 0],
[1, 1],
[1, 0],
[1, 1]])
Pearson Correlation Coefficient(皮尔逊相关系数)表示2个向量的线性相关程度。
先上公式:
ρ ( X , Y ) = ∑ i = 1 n ( X − μ x ) ( Y − μ y ) ∑ i = 1 n ( X i − μ x ) 2 ∑ i = 1 n ( Y i − μ y ) 2 \rho(X, Y) = \frac{\sum_{i=1}^n(X-\mu_x)(Y-\mu_y)}{\sqrt{\sum_{i=1}^n(X_i - \mu_x)^2}\sqrt{\sum_{i=1}^n(Y_i - \mu_y)^2}} ρ(X,Y)=∑i=1n(Xi−μx)2∑i=1n(Yi−μy)2∑i=1n(X−μx)(Y−μy)
可以看到分子是向量X和Y(也就是特征X和label Y)的协方差(Covariance),分母是X和Y方差的积。通俗的说,协方差描述2个向量线性相关的程度,如果一个变量跟随另一个变量同时变大或者变小,那么这两个变量的协方差就是正值,反之类似。但是X和Y的协方差的值比Z和Y的协方差值大,并不能代表X和Y的相关性比Z和Y的相关性强。为了消除这种类似于“量纲”不同带来的影响,于是将协方差除以2个向量的方差,即得到值在区间[-1, 1]的Pearson Correlation Coefficient(皮尔逊相关系数),-1表示2个变量完全负相关,1表示2个变量完全正相关。
**另一个我认为更好的解释是:**仔细观察上式,其其实是向量 X − μ x X-\mu_x X−μx 和 Y − μ y Y-\mu_y Y−μy 夹角的余弦值,我们知道,当余弦值为1,2个向量完全重合,即完全正相关,当余弦值为-1, 2个向量方向相反,即完全负相关。那为什么不直接计算2个向量的余弦值而是还需要减去各自的均值,回忆高中数学,向量都是以原点为起点,以终点坐标表示该向量,即所有向量的数字表示都在同一坐标系下,这里减均值起到相同的效果。
其实上面的解释,如果将 X − μ x X-\mu_x X−μx 和 Y − μ y Y-\mu_y Y−μy 看成一个整体,说的也就是余弦相似度,在NLP任务中,其常被用来度量2个词向量的相似度。
同时在运用Pearson方法时,有一个很重要的前提:要对其进行显著性检验。我们的数据是从真实世界采集的,不一定代表真实世界数据的分布,即存在抽样误差,这就导致我们计算的皮尔逊相关性系数不一定有意义。至于如何证明二者有意义,这篇文章就不详细说了。聪明的数学家想到使用T检验计算一个值P-value,如果P-value小于0.05(大部分研究使用),就表明有95%的置信度相信真实世界的数据是有相关性的(可网上搜索详细原理)。
这里附一张图,可视化皮尔逊相关系数取不同值时,数据分布大致长什么样:
>>> from scipy import stats
>>> a = np.array([0, 0, 0, 1, 1, 1, 1])
>>> b = np.arange(7)
>>> stats.pearsonr(a, b)
# 第一项Pearson相关系数,第二项P-value
(0.8660254037844386, 0.011724811003954649)
>>> stats.pearsonr([1, 2, 3, 4, 5], [10, 9, 2.5, 6, 4])
(-0.7426106572325057, 0.1505558088534455)
另外,pandas的corr()方法,也可批量计算Pearson相关性系数。
看到这里,来一个玩相关性的小游戏 Guess the Correlation
Spearman Correlation Coefficient(斯皮尔曼相关系数)表示2个向量的单调相关程度,即变量Y随X增大而增大或者减小的程度,其取值范围为[-1,1]。
先上公式:
ρ s = 1 − 6 ∑ d i 2 n ( n 2 − 1 ) \rho_s = 1 - \frac{6\sum{d_i^2}}{n(n^2 - 1)} ρs=1−n(n2−1)6∑di2
对于已知的向量X=[4,5,2]和Y=[7,4,6],首先将X和Y按大小进行排序,并按排序前X元素的位置,记下该元素排序后的次序。比如X从大往小排序后,4排第2位,5排第1位,2排第3位,排序后位置X’=[2,1,3], 同理得到Y’=[1,3,2].上式中的 ∑ d i 2 = ( 2 − 1 ) 2 + ( 1 − 3 ) 2 + ( 3 − 2 ) 2 \sum{d_i^2}=(2-1)^2+(1-3)^2+(3-2)^2 ∑di2=(2−1)2+(1−3)2+(3−2)2 ,n就是向量中数据的个数,代入上式可求的斯皮尔曼相关系数为0.25.
同样,斯皮尔曼方法也需要进行显著性检验,P-value的含义如上文介绍,不再赘述。
>>> from scipy import stats
>>> a = range(-5, 5)
>>> b = [x ** 2 for x in a] # 非单调
>>> c = [x ** 3 for x in a] # 单调递增
>>> stats.spearmanr(a, b)
SpearmanrResult(correlation=-0.27609440361293197, pvalue=0.44001452222946114)
>>> stats.spearmanr(a, c)
SpearmanrResult(correlation=0.9999999999999999, pvalue=6.646897422032013e-64)
另外,pandas的corr()方法,也可批量计算Spearman相关性系数
Part 1就写到这里,卡方检验、互信息和基于模型的特征选择方法可继续看part2、part3