特征选择方法详解Part1-方差分析、Pearson、Spearman

Content

  • 1. 基本方法
    • 1.1 专家推荐和业务理解
    • 1.2 方差分析
  • 2. 单变量分析
    • 2.1 Pearson Correlation Coefficient
      • 2.1.1 原理
      • 2.1.2 Notice
      • 2.1.3 使用示例
    • 2.2 Spearman Correlation Coefficient
      • 2.2.1 原理
      • 2.2.2 Notice
      • 2.2.3 使用示例
  • 3. 后续

特征选择系列:

  1. 特征选择方法详解Part1-方差分析、Pearson、Spearman

  2. 特征选择方法详解Part2-卡方检验、互信息(Mutual Information)

  3. 特征选择方法详解Part3-SelectFromModel-RFE、L1、Tree、Permutation importance

正常的机器学习项目,除了数据清洗,特征工程是最耗时和耗精力的步骤,也是对整个项目效果好坏起决定性作用的步骤之一。特征工程更多的是经验性的东西,当然所有的经验都建立在对基本方法的了解之上。本文将对特征工程中特征选择的常用方法方差分析、Pearson、Spearman进行介绍。

文章同步发在我的个人博客,欢迎大佬们指教。特征选择方法详解Part1-方差分析、Pearson、Spearman

1. 基本方法

1.1 专家推荐和业务理解

此种方法是最基本、最简单也是最重要的一步。

当数据准备好,几百个特征摆在眼前,如果我们对业务很熟悉,有比较深刻的理解,我们自然能知道哪些特征很重要,而哪些特征没什么用,这样就自然而然的去掉了一些特征,再继续使用其他方法进行特征选择。

而当我们对业务不太熟悉,或者没办法短时间内有很深刻的理解。比如说一个纯技术的同学,突然接到一个关于医疗的项目,我想最聪明的办法,去找医生聊一聊,让他们给一些建议。

1.2 方差分析

方差分析是一个简单、基本的特征选择方法。简单来说,方差越大的特征,认为其越有用,而方差越小的特征,因为每个样本在此特征的值比较接近或者相同,就认为其对模型训练没有作用。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]])

2. 单变量分析

2.1 Pearson Correlation Coefficient

2.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%的置信度相信真实世界的数据是有相关性的(可网上搜索详细原理)。

这里附一张图,可视化皮尔逊相关系数取不同值时,数据分布大致长什么样:

特征选择方法详解Part1-方差分析、Pearson、Spearman_第1张图片

2.1.2 Notice

  • 使用pearson方法的数据应满足正态分布。这是显著性检验方法T检验的前提。
  • 皮尔逊相关系数是用于衡量线性相关关系的,在不清楚数据分布的情况下,不能直接比较皮尔逊相关系数。比较简单的方法是画散点图看一下大概趋势。
  • 异常值会对结果产生较大影响。
  • 当皮尔逊相关系数为0,不能说明其完全不相关,可能是非线性相关。

2.1.3 使用示例

>>> 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

2.2 Spearman Correlation Coefficient

2.2.1 原理

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=1n(n21)6di2

对于已知的向量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=(21)2+(13)2+(32)2 ,n就是向量中数据的个数,代入上式可求的斯皮尔曼相关系数为0.25.

同样,斯皮尔曼方法也需要进行显著性检验,P-value的含义如上文介绍,不再赘述。

2.2.2 Notice

  • 使用斯皮尔曼方法,没有对数据分布的要求
  • 斯皮尔曼相关系数表示的是2个向量的单调相关程度,即变量Y随X增大而增大或者减小的程度,即使其值为0,也不能说明完全不相关,因为可能是其他非单调相关(可看下面代码示例)。

2.2.3 使用示例

>>> 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相关性系数

3. 后续

Part 1就写到这里,卡方检验、互信息和基于模型的特征选择方法可继续看part2、part3

你可能感兴趣的:(Machine,Learning)