基于sklearn的特征工程

| |

什么是特征工程?

Coming up with features is difficult, time-consuming, requires expert knowledge. “Applied machine learning” is basically feature engineering.
——Andrew Ng(吴恩达) 提取特征是困难的,耗时的,需要丰富的专家知识。“应用机器学习”从根本上来说就是特征工程

特征值化是为了计算机更好的去理解数据

特征抽取

class sklearn.feature_extraction.DictVectorizer(*, dtype=<class 'numpy.float64'>, separator='=', sparse=True, sort=True)

独热编码 One-hot

编码通常用于处理类别不具有大小关系的类别特征,最常见的用法是NLP中对词库中单词的编码。例如对于血型(A,B,O,AB),对应的One-hot编码可以表示为((1000),(0100),(0010),(0001))。对于范围特别大的常见,例如字典,生产的one-hot编码非常稀疏,需要节省存储空间。配合特征选择来降低特征维度。同样是为了解决高维情况下的存储问题。

python

data = [{'city': '北京','temperature':100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature':30}]
# 1、实例化一个转换器类,sparse=False指独热编码
transfer = DictVectorizer(sparse=False)
# 2、调用fit_transform
data = transfer.fit_transform(data)

文本特征提取

有空了再补充这里的内容

特征预处理

标准化 normalization

学习算法的目标函数中使用的许多元素(例如支持向量机的RBF内核或线性模型的l1和l2正则化器)都假定所有特征都围绕零为中心并且具有相同阶数的方差。如果某个特征的方差比其他特征大几个数量级,则它可能会极大影响目标函数,并使估计器无法按预期从其他特征中正确学习。
scale函数使数据变为 均值为0、方差为1 的数据集

python

>>> from sklearn import preprocessing
>>> import numpy as np
>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
>>> X_scaled = preprocessing.scale(X_train)

>>> X_scaled
array([[ 0.  ..., -1.22...,  1.33...],
       [ 1.22...,  0.  ..., -0.26...],
       [-1.22...,  1.22..., -1.06...]])

>>> X_scaled.mean(axis=0)
array([0., 0., 0.])

>>> X_scaled.std(axis=0)
array([1., 1., 1.])

StandardScaler

preprocessing模块还提供了一个实用程序类StandardScaler,它使TransformerAPI来计算训练集上的均值和标准差,以便以后能够在测试集上重新应用相同的转换。 很多ML的算法要求训练的输入参数的平均值是0并且有相同阶数的方差例如:RBF核的SVM,L1和L2正则的线性回归

class sklearn.preprocessing.StandardScaler(*, copy=True, with_mean=True, with_std=True)
copy 如果为false,就会用归一化的值替代原来的值;如果被标准化的数据不是np.array或scipy.sparse CSR matrix, 原来的数据还是被copy而不是被替代

能够查询的属性:

scale_: 缩放比例,同时也是标准差

mean_: 每个特征的平均值

var_:每个特征的方差

n_sample_seen_:样本数量,可以通过patial_fit 增加

fit_transform(X, y=None, **fit_params)
拟合数据,然后对其进行转换。

python

>>> from sklearn.preprocessing import StandardScaler
>>> data = [[0, 0], [0, 0], [1, 1], [1, 1]]
>>> scaler = StandardScaler()
>>> print(scaler.fit(data))
StandardScaler()
>>> print(scaler.mean_)
[0.5 0.5]
>>> print(scaler.transform(data))
[[-1. -1.]
 [-1. -1.]
 [ 1.  1.]
 [ 1.  1.]]
>>> print(scaler.transform([[2, 2]]))
[[3. 3.]]

z-score normalization

After z-score normalization, all features will have a mean of 0 and a standard deviation of 1.

To implement z-score normalization, adjust your input values as shown in this formula:

$$x^{(i)}_j = \dfrac{x^{(i)}_j - \mu_j}{\sigma_j} $$

where $j$ selects a feature or a column in the X matrix. $µ_j$ is the mean of all the values for feature (j) and $\sigma_j$ is the standard deviation of feature (j).

$$ \begin{align} \mu_j &= \frac{1}{m} \sum_{i=0}^{m-1} x^{(i)}_j \\ \sigma^2_j &= \frac{1}{m} \sum_{i=0}^{m-1} (x^{(i)}_j - \mu_j)^2 \end{align} $$

Implementation Note: When normalizing the features, it is important to store the values used for normalization - the mean value and the standard deviation used for the computations. After learning the parameters from the model, we often want to predict the prices of houses we have not seen before. Given a new x value (living room area and number of bed- rooms), we must first normalize x using the mean and standard deviation that we had previously computed from the training set.

Implementation

python

def zscore_normalize_features(X):
    """
    computes  X, zcore normalized by column

    Args:
      X (ndarray): Shape (m,n) input data, m examples, n features

    Returns:
      X_norm (ndarray): Shape (m,n)  input normalized by column
      mu (ndarray):     Shape (n,)   mean of each feature
      sigma (ndarray):  Shape (n,)   standard deviation of each feature
    """
    # find the mean of each column/feature
    mu     = np.mean(X, axis=0)                 # mu will have shape (n,)
    # find the standard deviation of each column/feature
    sigma  = np.std(X, axis=0)                  # sigma will have shape (n,)
    # element-wise, subtract mu for that column from each example, divide by std for that column
    X_norm = (X - mu) / sigma      

    return (X_norm, mu, sigma)

#check our work
#from sklearn.preprocessing import scale
#scale(X_orig, axis=0, with_mean=True, with_std=True, copy=True)

特征缩放 sklearn.preprocessing.MinMaxScaler

通过将每个要素缩放到给定范围来变换要素。该估计器分别缩放和转换每个特征,以使其在训练集上处于给定范围内,例如介于零和一之间。 计算原理为:

python

X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_scaled = X_std * (max - min) + min

示例:将简单的数据矩阵缩放到[0, 1]范围

python

>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
...
>>> min_max_scaler = preprocessing.MinMaxScaler()
>>> X_train_minmax = min_max_scaler.fit_transform(X_train)
>>> X_train_minmax
array([[0.5       , 0.        , 1.        ],
       [1.        , 0.5       , 0.33333333],
       [0.        , 1.        , 0.        ]])

示例:将数据中列名称为'milage','Liters','Consumtime'的三列数据缩放到(2,3)区间内

python

from sklearn.preprocessing import MinMaxScaler
# 1、实例化一个转换器类
transfer = MinMaxScaler(feature_range=(2, 3))
# 2、调用fit_transform
data = transfer.fit_transform(data[['milage','Liters','Consumtime']])

特征缩放时,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性较差,只适合传统精确小数据场景。一般情况下应该优先使用标准化。

特征降维

指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程。减少数据的冗余。
降维的目的是在不丢失太多信息的前提下简化数据。

特征选择

数据中包含冗余或无关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征。

低方差特征过滤

class sklearn.feature_selection.VarianceThreshold(threshold=0.0)
训练集方差低于此阈值的特征将被删除。默认设置是保留所有具有非零方差的特征,即删除所有样本中具有相同值的特征。
此特征选择算法仅查看特征(X),而不查看所需的输出(y),因此可用于无监督学习。

主成分分析 PCA降维

参阅文档

python

from sklearn.decomposition import PCA
# 1、实例化PCA, 小数——保留多少信息
transfer = PCA(n_components=0.9)
# 2、调用fit_transform
data1 = transfer.fit_transform(data)
python

>>> import numpy as np
>>> from sklearn.decomposition import PCA
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
>>> pca = PCA(n_components=2)
>>> pca.fit(X)
PCA(n_components=2)
>>> print(pca.explained_variance_ratio_)
[0.9924... 0.0075...]
>>> print(pca.singular_values_)
[6.30061... 0.54980...]

交叉验证

解决此问题的常见方法称为交叉验证:你只需保持训练集的一部分,以评估几种候选模型并选择最佳模型。新的保留集称为验证集,有时也称为开发集(dev set)。更具体地说,你可以在简化的训练集上(即完整训练集减去验证集)训练具有各种超参数的多个模型,并且选择在验证集上表现最佳的模型。在此交叉验证之后,你在完整的训练集(包括验证集)上训练最佳模型,这就是你的最终模型。最后,你在测试集上评估这个模型以获得泛化误差的估计值。
——《机器学习实战(原书第2版)》[法] Aurélien Géron