前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >预处理数据

预处理数据

作者头像
润森
发布2019-08-29 11:04:12
1.5K0
发布2019-08-29 11:04:12
举报
文章被收录于专栏:毛利学Python

预处理数据

数据预处理(data preprocessing)是指在主要的处理以前对数据进行的一些处理。

预处理数据包括

  • 数据的标准化
  • 映射到01均匀分布
  • 数据的归一化
  • 数据的二值化
  • 非线性转换
  • 数据特征编码
  • 处理缺失值等

该sklearn.preprocessing软件包提供了几个常用的实用程序函数和变换器类,用于将原始特征向量更改为更适合下游估计器的表示。

映射到统一分布

QuantileTransformerquantile_transform提供非参数转换以将数据映射到值为0到1的均匀分布

代码语言:javascript
复制
>>> from sklearn.datasets import load_iris
>>> from sklearn.model_selection import train_test_split
>>> iris = load_iris()
>>> X, y = iris.data, iris.target
>>> X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
>>> quantile_transformer = preprocessing.QuantileTransformer(random_state=0)
>>> X_train_trans = quantile_transformer.fit_transform(X_train)
>>> X_test_trans = quantile_transformer.transform(X_test)
>>> np.percentile(X_train[:, 0], [0, 25, 50, 75, 100]) 
array([ 4.3,  5.1,  5.8,  6.5,  7.9])

标准化,或平均删除和方差缩放

Standardization标准化:将特征数据的分布调整成标准正态分布,也叫高斯分布,也就是使得数据的均值维0,方差为1.

标准化的原因在于如果有些特征的方差过大,则会主导目标函数从而使参数估计器无法正确地去学习其他特征。 标准化的过程为两步:去均值的中心化(均值变为0);方差的规模化(方差变为1)。 在sklearn.preprocessing中提供了一个scale的方法,可以实现以上功能

代码语言:javascript
复制
from sklearn import preprocessing
import numpy as np
# 1. 标准化:去均值,方差规模化
# 在sklearn.preprocessing中提供了一个scale的方法,可以实现以上功能。
x = np.array([[1., -1., 2.],
              [2., 0., 0.],
              [0., 1., -1.]])
# 将每一列特征标准化为标准正态分布,注意,标准化是针对每一列而言的
x_scale = preprocessing.scale(x)
x_scale


array([[ 0.        , -1.22474487,  1.33630621],
       [ 1.22474487,  0.        , -0.26726124],
       [-1.22474487,  1.22474487, -1.06904497]])
  • 缩放数据的均值为0和单位方差为1:
代码语言:javascript
复制
In [10]: x_scale.mean(axis = 0)
Out[10]: array([ 0.00000000e+00, -7.40148683e-17,  0.00000000e+00])

In [11]: x_scale.std(axis=0)
Out[11]: array([1., 1., 1.])

StandarScaler preprocessing这个模块还提供了这一个实用类,它可以在训练数据集上做了标准转换操作之后,把相同的转换应用到测试训练集中。用于之后还有数据的加入

代码语言:javascript
复制
scaler = preprocessing.StandardScaler().fit(x)
#使用上面这个转换器去转换训练数据x,调用transform方法
scaler.transform(x)
------------
array([[ 0.        , -0.70710678,  1.22474487],
       [ 1.22474487,  1.41421356, -1.22474487],
       [-1.22474487, -0.70710678,  0.        ]])

#好了,比如现在又来了一组新的样本,也想得到相同的转换
new_x = [[-1., 1., 0.]]
scaler.transform(new_x)

#  array([[-2.44948974,  3.53553391, -1.22474487]])

MinMaxScaler 在MinMaxScaler中是给定了一个明确的最大值与最小值。它的计算公式如下:

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

代码语言:javascript
复制
#用的iris的数据 合二为一 进行标准化
from sklearn import preprocessing 
scaler = preprocessing.MinMaxScaler() #MinMaxSca ler将样本特征值线性缩放到0,1之间 
scaler.fit(iris.data)  #先fit 
data = scaler.transform(iris.data) #再transform.也可以二合一写成fit_transform 

数据的正则化(正则化有时也叫归一化)

什么是正则化

正则化方法是在训练数据不够多时,或者overtraining时,常常会导致过拟合(overfitting)。这时向原始模型引入额外信息,以便防止过拟合和提高模型泛化性能的一类方法的统称。在实际的深度学习场景中我们几乎总是会发现,最好的拟合模型(从最小化泛化误差的意义上)是一个适当正则化的大型模型。

正则化是缩放单个样本以具有单位范数的过程。正则化有时也叫归一化,正规化。如果你计划使用 二次形式(如点积或任何其他核函数)来量化任何样本间的相似度,则此过程将非常有用。

常用的向量范数有"l1"范数和"l2"范数

代码语言:javascript
复制
from sklearn import preprocessing 
X = [[ 1., -1.,  2.],     [ 2.,  0.,  0.],     [ 0.,  1., -1.]]
# 使用normalize函数 
X_normalized = preprocessing.normalize(X, norm='l2')
print(X_normalized)
# 也可以使用Normalizer类
normalizer = preprocessing.Normalizer(norm = 'l1') 
normalizer.fit(X) #fit does nothing 
normalizer.transform(X)

按行操作,把每一行变成单位长度!!

代码语言:javascript
复制
[[ 0.40824829 -0.40824829  0.81649658]
 [ 1.          0.          0.        ]
 [ 0.          0.70710678 -0.70710678]]
array([[ 0.25, -0.25,  0.5 ],
       [ 1.  ,  0.  ,  0.  ],
       [ 0.  ,  0.5 , -0.5 ]])
  • 当norm=’max’ 时,则对每条样本取最大值,然后每条样本与其最大值相除即可
  • 当norm=’l1’ 时,则对每条样本取其L1范数,然后每条样本与其相除即可
  • 当norm=’l2’ 时,则对每条样本取其L2范数,然后每条样本与其相除即可

特征的二值化

特征二值化是将数值特征用阈值过滤得到布尔值的过程。 将大于0的变成1 ,小于等于0 变成0 这里的阈值是0

代码语言:javascript
复制
x = [ [ 1., 1.,  2.],     
      [ 2.,  0.,  0.],     
      [ 0.,  1., -1.]] 
binarizer=preprocessing.Binarizer().fit(x)
print(binarizer)
#Binarizer(copy=True, threshold=0.0)
print(binarizer.transform(x))

代码语言:javascript
复制
Binarizer(copy=True, threshold=0.0)
[[1. 1. 1.]
 [1. 0. 0.]
 [0. 1. 0.]]

怎么设置阈值

代码语言:javascript
复制
a = [[ 1., 1.,  2.],     [ 2.,  0.,  0.],     [ 0.,  1., -1.]] 
binarizer = preprocessing.Binarizer(threshold=1).fit(x)
print(binarizer)
binarizer.transform(a)
OUT:
    Binarizer(copy=True, threshold=1)
    array([[0., 0., 1.],
           [1., 0., 0.],
           [0., 0., 0.]])

分类特征编码

在机器学习中,特征经常不是数值型的而是分类型(标称型)的。举个例子,一个人的性别可能是 "male"或 "female"两者之一。我们可以用0来表示"male",1来表示"female"。但是这样做的话,性别 特征就变得有序了。

为了解决这个问题,我们可以使用一种叫做"one-of-K"或称做"one-hot"(独热)的编码方式。即两 个特征值来进行编码性别[1,0]表示"male",而[0,1]表示"female"。通常使用"one-hot"方式编码后会 增加数据的维度和稀疏性。

a 是一个4X3列表,从列看,第一列有0,1 两个特征,第二列有0,1,2 三个特征,第三列有0,1,2,3 四个特征,一共9个,所以输出的第一行[1,0] 代表 向量的第一个数字 0 即第一个特征 0 有 ,第二个特征 1 没有,[1,0,0] 代表 0 [0,0,0,1] 代表3, ([[1., 0., 1., 0., 0., 0., 0., 0., 1.], 就是 [0, 0, 3]

代码语言:javascript
复制
from sklearn import preprocessing 
a = [[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]] 
onehot = preprocessing.OneHotEncoder()  #n_values=[2,3,4]
onehot.fit_transform(a).toarray()  # 将稀疏矩阵转化为普通矩阵
OUT:
array([[1., 0., 1., 0., 0., 0., 0., 0., 1.],
       [0., 1., 0., 1., 0., 1., 0., 0., 0.],
       [1., 0., 0., 0., 1., 0., 1., 0., 0.],
       [0., 1., 1., 0., 0., 0., 0., 1., 0.]])

还可以在categories_属性中找到对应的特征

代码语言:javascript
复制
In [17]: onehot.categories_
Out[17]: [array([0., 1.]), array([0., 1., 2.]), array([0., 1., 2., 3.])]

有丢失的分类特征值处理

如果训练集中有丢失的分类特征值,必须显式地设置 n_values 假设第二列有4个特征,少了一个,设置n_values=[2,4,4],所以输出一行10个

代码语言:javascript
复制
encoder = preprocessing.OneHotEncoder(n_values=[2,4,4])   # [2,4,4]设置美航对应的特征数
encoder.fit_transform(a).toarray()
OUT:
array([[1., 0., 1., 0., 0., 0., 0., 0., 0., 1.],
       [0., 1., 0., 1., 0., 0., 1., 0., 0., 0.],
       [1., 0., 0., 0., 1., 0., 0., 1., 0., 0.],
       [0., 1., 1., 0., 0., 0., 0., 0., 1., 0.]])

处理缺失值

因为各种各样的原因,真实世界中的许多数据集都包含缺失数据,这类数据经常被编码成空格、 NaN,或者是其他的占位符。但是这样的数据集并不能和scikit-learn学习算法兼容

pandas方法
  • 直接舍弃(不推荐) 一个特征数据出了问题但还是有利用价值、
代码语言:javascript
复制
from numpy import nan as NA
import pandas as pd
data = pd.Series([1,NA,3,Na,7])
data.dropna()
  • 补全缺失值
代码语言:javascript
复制
data.fillna(0)
data.fillna(data.mean()
  • 补充删掉重复值 data.drop_duplicates()
sklearn 方法
代码语言:javascript
复制
import numpy as np 
from sklearn.preprocessing import Imputer
# 策略有 mean,most_fr equent(众数),median(中位数)
imp = Imputer(missing_values='NaN', strategy='mean', axis=0) 
imp.fit([[1, 5], [np.nan, 7], [7, 6]]) 
#fit求得第一列特征均值为4,第二列特征均值为6
X = [[np.nan, 2], [6, np.nan], [7, 6]] 
print(imp.transform(X))   
OUT:
[[4. 2.]
 [6. 6.]
 [7. 6.]]   

生成多项式特征

机器学习,通常会给一定的特征数据进行分类或者回归预测。有时需要构建更多的特征,然后对特征再进行特征选择。通过增加一些输入数据的非线性特征来增加模型的复杂度通常是有效的。一个简单通用的办法是使用多项式特征,这可以获得特征的更高维度和互相间关系的项。这在PolynomialFeatures中实现:

代码语言:javascript
复制
>>> X = np.arange(6).reshape(3, 2)
>>> X
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> 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.]])
# X 的特征已经从 (x1,x2) 转换为(1,x1,x2,x1^2,x1*x2,x2^2,)
>>> poly = PolynomialFeatures(interaction_only=True)
>>> poly.fit_transform(X)
array([[  1.,   0.,   1.,   0.],
       [  1.,   2.,   3.,   6.],
       [  1.,   4.,   5.,  20.]])
# X 的特征已经从 (x1,x2) 转换为(1,x1,x2,x1*x2)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小刘IT教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 预处理数据
  • 映射到统一分布
  • 标准化,或平均删除和方差缩放
  • 数据的正则化(正则化有时也叫归一化)
  • 特征的二值化
  • 怎么设置阈值
  • 分类特征编码
  • 有丢失的分类特征值处理
  • 处理缺失值
    • pandas方法
      • sklearn 方法
      • 生成多项式特征
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档