推荐书: Python开发最佳实践

机器学习数据预处理技术(二值化-连续化-估计缺失值-多项式)

分享时@该用户已经被封, 我就能回答你的问题奥!

文章目录
  1. 1. 简介
  2. 2. 数据预处理技术介绍
  3. 3. 二值化
    1. 3.1. 特征二值化
  4. 4. 分类数据连续化
  5. 5. 估算缺失的值
  6. 6. 生成多项式特征


本篇文章继承上篇文章机器学习数据预处理技术(标准化-缩放-正则化)

简介

机器学习模型千变万化, 每种模型需要的数据形式都略有不同, 所以我们一般花在数据提取/清理/格式化等操作的时间可能会占项目总时间的百分之七十(甚至更多)。

不过, 借助别人已经写好的程序可以让我们的工作事半功倍。今天我们介绍的一个工具就是著名的python机器学习库sklearn, 它包含很多数据预处理技术, 下面我们就来列出常用的一些数据预处理技术, 以便大家提高效率, 也是给我自己的一个技术笔记。

数据预处理技术介绍

数据集的标准化是scikit-learn中实现的许多机器学习估计器的通用要求;如果单个特征看起来不像标准正态分布数据那么它们可能会表现得很差:高斯分布的零均值和单位方差。

在实践中,我们经常忽略分布的形状,只是通过去除每个特征的平均值来将数据转化为中心,然后通过将特征向量除以它们的标准差来对其进行调整。

例如,学习算法的目标函数(如支持向量机的RBF核或线性模型的l1和l2正则化)中使用的许多元素都假定所有特征都以零为中心并具有相同数量级的方差。如果一个特征的方差比其他特征要大几个数量级,那么它可能会影响目标函数,使得算法无法正确地按照预期正确地学习其他特征。

二值化

特征二值化

根据阈值将数据二值化(将特征值设置为0或1)大于阈值的值映射到1,而小于或等于阈值的值映射到0.默认阈值为0时,只有正值映射到1。二值化是文本计数数据的常用操作,分析人员可以决定只考虑是否存在某个特征,而不是量化出现次数。它也可以用作考虑布尔随机变量的估计器的预处理步骤(例如,在贝叶斯设置中使用伯努利分布建模)。

特征二值化是对数值特征进行阈值处理以获得布尔值的过程。这对下游概率估计器非常有用,它可以假定输入数据是根据多变量伯努利分布分布的。例如,sklearn.neural_network.BernoulliRBM就是这种情况。

即使归一化计数(也称为术语频率)或TF-IDF值的特征在实践中经常稍微好一点,在文本处理社区中也使用二进制特征值(可能简化概率推理)也是常见的。

至于Normalizer,实用程序类Binarizer意味着在sklearn.pipeline.Pipeline的早期阶段使用。拟合方法不会做任何事情,因为每个样本都是独立处理的:

1
2
3
4
5
from sklearn import preprocessing
import numpy as np
np.random.seed(1)
X = np.random.rand(3,3)
X
输出: array([[4.17022005e-01, 7.20324493e-01, 1.14374817e-04], [3.02332573e-01, 1.46755891e-01, 9.23385948e-02], [1.86260211e-01, 3.45560727e-01, 3.96767474e-01]])
1
2
3
# 建议显性设置阈值
binarizer = preprocessing.Binarizer(threshold=0.5)
binarizer.transform(X)
输出: array([[0., 1., 0.], [0., 0., 0.], [0., 0., 0.]])
1
2
binarizer = preprocessing.Binarizer(threshold=0.3)
binarizer.transform(X)
输出: array([[1., 1., 0.], [1., 0., 0.], [0., 1., 1.]])

分类数据连续化

通常,特征不是作为连续值给出的,而是文本字符串或者数字编码的类别。比如性别数据通常是["男", "女"]这样的数据, 可以编码成[1,2], 但是这种数据通常不是可以直接进入机器学习模型的。将这种分类数据进行连续化的方法最著名的就是one-hot-encoding。默认情况下,每个功能可以从数据集中自动推断出多少个值。可以使用参数n_values明确指定。在我们的数据集中有两种性别,三种可能的大陆和四种网页浏览器。然后我们拟合估计量,并转换数据点。结果是,前两个数字编码性别,下一组三个数字大洲和最后四个网络浏览器。

1
2
3
4
5
6
7
8
9
10
# 这是三列分类数据
# 在我们的数据集中有两种性别,三种可能的大陆和四种网页浏览器。
X = [[0, 0, 3],
[1, 1, 0],
[0, 2, 1],
[1, 0, 2]]

enc = preprocessing.OneHotEncoder()
enc.fit(X)
enc.transform([[0, 1, 3]]).toarray()
输出: array([[1., 0., 0., 1., 0., 0., 0., 0., 1.]])

请注意,如果训练数据可能缺少分类特征,则必须明确设置n_values。例如,假如有三种性别:

1
2
3
enc = preprocessing.OneHotEncoder(n_values=[3, 3, 4])
enc.fit(X)
enc.transform([[0, 1, 3]]).toarray()
输出: array([[1., 0., 0., 0., 1., 0., 0., 0., 0., 1.]])

估算缺失的值

由于各种原因,许多真实世界的数据集包含缺失值,通常编码为空白,NaN或其他占位符。然而,这样的数据集与scikit-learn估计器不兼容,它们假定数组中的所有值都是数值的,并且都具有并保持含义。使用不完整数据集的基本策略是放弃包含缺失值的整个行和/或列。然而,这是以丢失可能有价值的数据为代价的(尽管不完整)。更好的策略是推算缺失值,即从数据的已知部分推断它们。

Imputer类提供了输入缺失值的基本策略,可以使用缺失值所在的行或列的均值,中位数或最频繁值。这个类还允许不同的缺失值编码。

以下代码片段演示了如何使用包含缺失值的列(轴0)的平均值替换缺失值(编码为np.nan):

1
2
3
4
5
6
7
import numpy as np
from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
imp.fit([[1, 2], [np.nan, 3], [7, 6]])

X = [[np.nan, 2], [6, np.nan], [7, 6]]
print(imp.transform(X))
输出: [[4. 2. ] [6. 3.66666667] [7. 6. ]]

稀疏矩阵:

1
2
3
4
5
6
7
import scipy.sparse as sp
X = sp.csc_matrix([[1, 2], [0, 3], [7, 6]])
imp = Imputer(missing_values=0, strategy='mean', axis=0)
imp.fit(X)

X_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]])
print(imp.transform(X_test))
输出: [[4. 2. ] [6. 3.66666667] [7. 6. ]]

生成多项式特征

考虑到输入数据的非线性特征,往往会增加模型的复杂性。一种简单而常用的方法是多项式特征,它可以得到特征的高阶和交互项。它在PolynomialFeatures中实现:

将X的特征(X_1,X_2)变换为(1,X_1,X_2,X_1^2,X_1X_2,X_2^2):

1
2
3
4
import numpy as np
from sklearn.preprocessing import PolynomialFeatures
X = np.arange(6).reshape(3, 2)
X
输出: array([[0, 1], [2, 3], [4, 5]])
1
2
poly = PolynomialFeatures(2)
poly.fit_transform(X)
输出: array([[ 1., 0., 1., 0., 0., 1.], [ 1., 2., 3., 4., 6., 9.], [ 1., 4., 5., 16., 20., 25.]])

注意
本文由jupyter notebook转换而来, 您可以在这里下载notebook.ipynb)
有问题可以直接在下方留言
或者给我发邮件675495787[at]qq.com
请记住我的网址: mlln.cn 或者 jupyter.cn