---
cid: 89
title: 浅谈特征工程 Feature  Engineering
slug: 89
date: 2019/09/08 16:05:25
updated: 2019/09/08 16:05:25
status: publish
author: harumonia
categories:
  - 源流清泉
tags:
  - 特征工程
noThumbInfoStyle: default
outdatedNotice: no
thumbChoice: default
thumbStyle: default
hidden: false
---

至此,看过了很多的机器学习的文章,发现大多是重于算法的讲解,但是机器学习是 _对数据集进行算法处理_ ,数据集的重要地位不言而喻.
个人认为,优质的数据集可以极大地提高模型精度和运算效率.一个很好的例子就是 sklearn 的 dataset,处理起来顺滑无比,但是在对上一篇文章所讲的泰坦尼克数据集进行机器学习时,如果也像在鸢尾花集上那样,结果自然是惨不忍睹.
所以这里单开一篇讲一下特征工程.

参考资料:  
kaggle-sina\Anisotropic  
$Feature\ Engineering$  
Tsai

ps.
基础的一些处理可以直接使用 numpy+pandas,灵活小巧.
不过如果涉及到一些统计方法,那么建议使用 sklearn 封装好的类.

# 数据预处理

## 无量纲化

在机器学习算法实践中，我们往往有着将不同规格的数据转换到同一规格，或不同分布的数据转换到某个特定分布 的需求，这种需求统称为将数据“无量纲化”。譬如梯度和矩阵为核心的算法中，譬如逻辑回归，支持向量机，神经 网络，无量纲化可以加快求解速度.

数据的无量纲化可以是线性的，也可以是非线性的。
线性的无量纲化包括中心化(Zero-centered 或者 Mean- subtraction)处理和缩放处理(Scale)。

### 数据归一化

当数据(x)按照最小值中心化后，再按极差(最大值 - 最小值)缩放，数据移动了最小值个单位，并且会被收敛到[0,1]之间，而这个过程，就叫做数据归一化(Normalization，又称 Min-Max Scaling)。 _归一化之后的数据服从正态分布._

> MinMaxScaler 在不涉及距离度量、梯度、协方差计算以及数据需要被压缩到特定区间时使用广泛，比如数字图像
> 处理中量化像素强度时，都会使用 MinMaxScaler 将数据压缩于[0,1]区间之中。

ps.使用 numpy 也可以快速实现归一化,不过在对大量数据进行处理时效率不及 sklearn

### 数据标准化

当数据(x)按均值(μ)中心化后，再按标准差(σ)缩放，数据就会服从为均值为 0，方差为 1 的正态分布(即标准正态分 布)，而这个过程，就叫做数据标准化(Standardization，又称 Z-score normalization).

### 小结

大多数机器学习算法中，会选择 StandardScaler 来进行特征缩放，因为 MinMaxScaler 对异常值非常敏
感。在 PCA，聚类，逻辑回归，支持向量机，神经网络这些算法中，StandardScaler 往往是最好的选择。

<!-- [![image.md.png](http://www.harumonia.top/images/2019/09/08/image.md.png)](http://www.harumonia.top/image/lXOG) -->

## 缺失值 SimpleImputer

在 **使用随机森林解决"泰坦尼克幸存"问题(1)** 一文中,我使用了 replace 来进行缺失值的填补,不过 sklearn 中内置了 SimpleImputer 来完成这项工作.

## 编码与哑变量

为了让数据适应算法和库，我们必须将数据进行编码，即是说，将文字型数据转换为数值型。

### 编码

- LabelEncoder:标签专用，能够将分类转换为分类数值
- OrdinalEncoder:特征专用，能够将分类特征转换为分类数值

### 哑变量

把分类转换成数字的时候，忽略了数字中自带的数学性质，所以给算法传达了一些不准确的信息，而这会影响我们的建模。
OrdinalEncoder 可以用来处理有序变量，但对于名义变量，我们只有使用哑变量的方式来处理，才能够尽量向算法传达最准确的信息

## 二值化与分段

用来处理连续型特征.

### 二值化

根据阈值将数据二值化(将特征值设置为 0 或 1)，用于处理连续型变量。大于阈值的值映射为 1，而小于或等于阈值的值映射为 0.

### 分段

将连续型变量划分为分类变量,也就是常说的分箱.

注意分箱的编码方式和定义箱宽的方式

# 特征选择 feature_selection

| 特征提取(feature extraction)                                                                                                       | 特征创造(feature creation)                                                                                                                              | 特征选择(feature selection)                                                                    |
| ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| 从文字，图像，声音等其他非结构化数据中提取新信息作为特征。比如说，从淘宝宝贝的名称中提取出产品类别，产品颜色，是否是网红产品等等。 | 把现有特征进行组合，或互相计算，得到新的特征。比如说，我们有一列特征是速度，一列特征是距离，我们就可以通过让两列相处，创造新的特征:通过距离所花的时间。 | 从所有的特征中，选择出有意义，对模型有帮助的特征，以避免必须将所有特征都导入模型去训练的情况。 |

## 过滤法 Filter

过滤方法通常用作预处理步骤，特征选择完全独立于任何机器学习算法。它是根据各种统计检验中的分数以及相关性的各项指标来选择特征。

过滤法的主要对象是:需要遍历特征或升维的算法们，而过滤法的主要目的是:在维持算法表现的前提下，帮助算法们降低计算成本。

### 方差过滤

这是通过特征本身的方差来筛选特征的类。比如一个特征本身的方差很小，就表示样本在这个特征上基本没有差异，可能特征中的大多数值都一样，甚至整个特征的取值都相同，那这个特征对于样本区分没有什么作用。所以无论接下来的特征工程要做什么，都要优先消除方差为 0 的特征。

### 相关性过滤

我们希望选出与标签相关且有意义的特征，因为这样的特征能够为我们提供大量信息。如果特征与标签无关，那只会白白浪费我们的计算内存，可能还会给模型带来噪音。

#### 卡方过滤

卡方过滤是专门针对离散型标签(即分类问题)的相关性过滤。
再结合 **feature_selection.SelectKBest** 这个可以输入”评分标准“来选出前 K 个分数最高的特征的类，我们可以借此除去最可能独立于标签，与我们分类目的无关的特征。

卡方检验的本质是推测两组数据之间的差异，其检验的原假设是”两组数据是相互独立的”。卡方检验返回卡方值和 P 值两个统计量，其中卡方值很难界定有效的范围，而 p 值，我们一般使用 0.01 或 0.05 作为显著性水平，即 p 值判断的边界.

#### F 检验

F 检验，又称 ANOVA，方差齐性检验，是用来捕捉每个特征与标签之间的线性关系的过滤方法。

F 检验的本质是寻找两组数据之间的线性关系，其原假设是”数据不存在显著的线性关系“。它返回 F 值和 p 值两个统计量。
和卡方过滤一样，我们希望选取 p 值小于 0.05 或 0.01 的特征，这些特征与标签时显著线性相关的，而 p 值大于 0.05 或 0.01 的特征则被我们认为是和标签没有显著线性关系的特征，应该被删除。

#### 互信息法

互信息法是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法。
不过 互信息法比 F 检验更加强大，F 检验只能够找出线性关系，而互信息法可以找出任意关系。

## 嵌入法 Embedded

嵌入法是一种让算法自己决定使用哪些特征的方法，即特征选择和算法训练同时进行。在使用嵌入法时，我们先使 用某些机器学习的算法和模型进行训练，得到各个特征的权值系数，根据权值系数从大到小选择特征。

_相比于过滤法，嵌入法的结果会更加精确到模型的效用本身，对于提高模型效力有更好的效果。并且，由于考虑特 征对模型的贡献，因此无关的特征(需要相关性过滤的特征)和无区分度的特征(需要方差过滤的特征)都会因为 缺乏对模型的贡献而被删除掉，可谓是过滤法的进化版。_

嵌入法引入了算法来挑选特征，因此其计算速度也会和应用的算法有很大的关系。如果采用计算量很大，计算缓慢的算法，嵌入法本身也会非常耗时耗力。并且，在选择完毕之后，我们还是需要自己来评估模型。

**在算法本身很复杂的时候，过滤法的计算远远比嵌入法要 快，所以大型数据中，我们还是会优先考虑过滤法。**

## 包装法 Wrapper

包装法也是一个特征选择和算法训练同时进行的方法，与嵌入法十分相似，它也是依赖于算法自身的选择,但不同的是，我们往往使用一个目标函数作为黑盒来帮 助我们选取特征，而不是自己输入某个评估指标或统计量的阈值。

**包装法要使用特征子集进行多次训练，因此它所需要的计算成本是最高的。**

最典型的目标函数是递归特征消除法(Recursive feature elimination, 简写为 RFE)。它是一种贪婪的优化算法， 旨在找到性能最佳的特征子集。 它反复创建模型，并在每次迭代时保留最佳特征或剔除最差特征，下一次迭代时， 它会使用上一次建模中没有被选中的特征来构建下一个模型，直到所有特征都耗尽为止。 然后，它根据自己保留或 剔除特征的顺序来对特征进行排名，最终选出一个最佳子集。包装法的效果是所有特征选择方法中最利于提升模型 表现的，它可以使用很少的特征达到很优秀的效果。除此之外，在特征数目相同时，包装法和嵌入法的效果能够匹 敌，不过它比嵌入法算得更见缓慢，所以也不适用于太大型的数据。相比之下， **包装法是最能保证模型效果的特征 选择方法** 。
