数据预处理(data preprocessing)是指在主要的处理以前对数据进行的一些处理。
预处理数据包括
该sklearn.preprocessing软件包提供了几个常用的实用程序函数和变换器类,用于将原始特征向量更改为更适合下游估计器的表示。
QuantileTransformer
并quantile_transform
提供非参数转换以将数据映射到值为0到1的均匀分布
>>> 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的方法,可以实现以上功能
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]])
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这个模块还提供了这一个实用类,它可以在训练数据集上做了标准转换操作之后,把相同的转换应用到测试训练集中。用于之后还有数据的加入
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
#用的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"范数
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)
按行操作,把每一行变成单位长度!!
[[ 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 ]])
特征二值化是将数值特征用阈值过滤得到布尔值的过程。 将大于0的变成1 ,小于等于0 变成0 这里的阈值是0
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))
Binarizer(copy=True, threshold=0.0)
[[1. 1. 1.]
[1. 0. 0.]
[0. 1. 0.]]
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]
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_属性中找到对应的特征
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个
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学习算法兼容
from numpy import nan as NA
import pandas as pd
data = pd.Series([1,NA,3,Na,7])
data.dropna()
data.fillna(0)
data.fillna(data.mean()
data.drop_duplicates()
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
中实现:
>>> 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)