该操作是对每一列进行变换。
这种方法基于原始数据的均值和标准差进行数据的标准化。将特征A的原始值x使用Z-score标准化到x’。
z-score标准化方法适用于特征A的最大值和最小值未知的情况,或有超出取值范围的离群数据的情况。
具体过程为将数据按其特征(按列进行)减去其均值,然后除以其方差。
最后得到的结果是,对每个特征/每列来说所有数据都聚集在0附近,即均值为0,方差值为1。
数学公式如下(LaTex数学公式文档):
x ′ = x − x m e a n x s t d x' = \frac {x - x_{mean}} {x_{std}} x′=xstdx−xmean
sklearn库中的preprocessing模块中的scale方法为数组形状的数据集的标准化提供了一个快捷实现:
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.])
Min-max标准化方法是对原始数据进行线性变换。设minA和maxA分别为特征A的最小值和最大值,将A的一个原始值x通过min-max标准化映射成在区间[0,1]中的值x’,其公式为:
x ′ = x − x m i n x m a x − x m i n x' = \frac {x-x_{min}} {x_{max} - x_{min}} x′=xmax−xminx−xmin
可以使用MinMaxScaler方法实现,以下是一个将简单的数据矩阵缩放到[0, 1]的例子:
from sklearn.preprocessing import MinMaxScaler
import numpy as np
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
X_train_minmax = MinMaxScaler().fit_transform(X_train)
>>> X_train_minmax
array([[ 0.5 , 0. , 1. ],
[ 1. , 0.5 , 0.33333333],
[ 0. , 1. , 0. ]])
MaxAbs的工作原理与Min-max非常相似,但是它只通过除以每个特征的最大值将训练数据特征缩放至 [-1, 1] 范围内,这就意味着,训练数据应该是已经零中心化或者是稀疏数据。公式如下: x ′ = x x m a x x' = \frac x {x_{max}} x′=xmaxx
可以使用MaxAbsScale方法实现,以下是使用上例中数据运用这个缩放器的例子:
from sklearn.preprocessing import MaxAbsScaler
import numpy as np
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
X_train_maxabs = MaxAbsScaler().fit_transform(X_train)
>>> X_train_maxabs
array([[ 0.5, -1. , 1. ],
[ 1. , 0. , 0. ],
[ 0. , 1. , -0.5]])
非线性转换就是将我们的特征映射到均匀分布或者高斯分布(即正态分布),相比线性缩放,该方法不受异常值影响。
该方法不受异常值影响,它将数据映射到了零到一的均匀分布上,将最大的数映射为1,最小的数映射为0。其它的数按从小到大的顺序均匀分布在0到1之间,如有相同的数则取平均值。
如数据为np.array([[1],[2],[3],[4],[5]]),则经过转换为:np.array([[0],[0.25],[0.5],[0.75],[1]]);
数据为np.array([[1],[2],[9],[10],[2]])则经过转换为:np.array([[0],[0.375],[0.75],[1.0],[0.375]])。
第二个例子具体过程如下图:
在sklearn中使用QuantileTransformer方法实现,用法如下:
from sklearn.preprocessing import QuantileTransformer
import numpy as np
data = np.array([[1],[2],[3],[4],[5]])
quantile_transformer = QuantileTransformer(random_state=666)
data = quantile_transformer.fit_transform(data)
>>>data
array([[0. ],
[0.25],
[0.5 ],
[0.75],
[1. ]])
映射到高斯分布是为了稳定方差,并最小化偏差。
在最新版sklearn 0.20.x中PowerTransformer现在有两种映射方法,Yeo-Johnson映射,公式如下:
在sklearn 0.20.x中使用PowerTransformer方法实现,用法如下:
from sklearn.preprocessing import PowerTransformer
import numpy as np
data = np.array([[1],[2],[3],[4],[5]])
data = PowerTransformer(method='box-cox', standardize=False).fit_transform(data)
sklearn 0.19.x,通过对QuantileTransformer设置参数output_distribution='normal’实现映射高斯分布,用法如下:
from sklearn.preprocessing import QuantileTransformer
import numpy as np
data = np.array([[1],[2],[3],[4],[5]])
quantile_transformer = QuantileTransformer(output_distribution='normal',random_state=666)
data = quantile_transformer.fit_transform(data)
data = np.around(data,decimals=3)
>>>data
array([[-5.199],
[-0.674],
[ 0. ],
[ 0.674],
[ 5.199]])
归一化是缩放单个样本以具有单位范数的过程。归一化实质是一种线性变换,线性变换有很多良好的性质,这些性质决定了对数据改变后不会造成“失效”,反而能提高数据的表现,这些性质是归一化的前提。归一化能够加快模型训练速度,统一特征量纲,避免数值太大。值得注意的是,归一化是对每一个样本做转换,所以是对数据的每一行进行变换,之前的方法都是对列进行变换。
L1范式定义如下:
∣ ∣ x ∣ ∣ 1 = ∑ i = 1 n ∣ x i ∣ ||x||_1 = \sum_{i=1}^{n} |x_i| ∣∣x∣∣1=i=1∑n∣xi∣
表示向量x中每个元素的绝对值之和,L1范式归一化就是将样本中每个特征除以特征的L1范式。
在sklearn中使用normalize方法实现,用法如下:
from sklearn.preprocessing import normalize
data = np.array([[-1,0,1],
[1,0,1],
[1,2,3]])
data = normalize(data,'l1')
>>>data
array([[-0.5 , 0. , 0.5 ],
[ 0.5 , 0. , 0.5 ],
[ 0.167, 0.333, 0.5 ]])
L2范式定义如下: ∣ ∣ x ∣ ∣ 2 = ∑ i = 1 n x i 2 ||x||_2 = \sqrt {\sum_{i=1}^n x_i^2} ∣∣x∣∣2=i=1∑nxi2表示向量元素的平方和再开平方根。
L2范式归一化就是将样本中每个特征除以特征的L2范式。
在sklearn中使用normalize方法实现,用法如下:
from sklearn.preprocessing import normalize
data = np.array([[-1,0,1],
[1,0,1],
[1,2,3]])
data = normalize(data,'l2')
>>>data
array([[-0.707, 0. , 0.707],
[ 0.707, 0. , 0.707],
[ 0.267, 0.535, 0.802]])
在数据挖掘中,特征经常是数值型的而不是分类型的,那么可以通过对特征进行编码,实现将标签编码为数值来表示的目标。
在数据挖掘中,特征经常不是数值型的而是分类型的。举个例子,一个人可能有[“male”, “female”],[“from Europe”, “from US”, “from Asia”],[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]等分类的特征。
这些特征能够被有效地编码成整数,比如[“male”, “from US”, “uses Internet Explorer”]可以被表示为[0, 1, 3],[“female”, “from Asia”, “uses Chrome”]表示为[1, 2, 1]。
在sklearn中,通过LabelEncoder方法来实现:
from sklearn.preprocessing import LabelEncoder
label = ['male','female']
label = LabelEncoder().fit_transform(label)
>>>label
array([1, 0])
这种整数特征表示并不能在sklearn的估计器中直接使用,因为这样的连续输入,估计器会认为类别之间是有序的,但实际却是无序的。如将male,female,转换为1,0。1比0要大,机器就会把这个关系考虑进去,而male,female之间是没有这样的关系的。所以我们需要使用另外一种编码方式,OneHot编码。
在sklearn中通过OneHotEncoder方法来实现,使用方法如下:
import numpy as np
from sklearn.preprocessing import OneHotEncoder
label = np.array([1,0])
label = np.array(label).reshape(len(label),1)#先将X组织成(sample,feature)的格式
label = OneHotEncoder().fit_transform(label).toarray()
>>>label
array([[0., 1.],
[1., 0.]])
在数据挖掘中,获取数据的代价经常是非常高昂的。所以有时就需要人为的制造一些特征,并且有的特征之间是有关联的。生成多项式特征可以轻松的为我们获取更多的数据,并获得特征的更高维度和互相间关系的项且引入了特征之间的非线性关系,可以有效的增加模型的复杂度。
在sklearn中通过PolynomialFeatures方法来生成多项式特征,使用方法如下:
import numpy as np
from sklearn.preprocessing import PolynomialFeatures
data = np.arange(6).reshape(3, 2)
# degree=n表示生成n项式特征,只需要特征之间交互
data = PolynomialFeatures(degree=2, interaction_only=True).fit_transform(data)
>>>data
array([[ 1., 0., 1., 0.],
[ 1., 2., 3., 6.],
[ 1., 4., 5., 20.]])
由于各种原因,真实世界中的许多数据集都包含缺失数据,这类数据经常被编码成空格、NaNs,或者是其他的占位符。
但是这样的数据集并不能被sklearn学习算法兼容,因为大多的学习算法都默认假设数组中的元素都是数值,因而所有的元素都有自己的意义。
使用不完整的数据集的一个基本策略就是舍弃掉整行或整列包含缺失值的数据。
但是这样就付出了舍弃可能有价值数据(即使是不完整的 )的代价。
处理缺失数值的一个更好的策略就是从已有的数据推断出缺失的数值。
sklearn中使用Imputer方法估算缺失值,使用方法如下:
from sklearn.preprocessing import Imputer
data = [[np.nan, 2], [6, np.nan], [7, 4],[np.nan,4]]
# 缺失值为nan,沿着每一列,使用平均值来代替缺失值
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
data = imp.fit_transform(data)
>>>data
array([[6.5 , 2. ],
[6. , 3.33333333],
[7. , 4. ],
[6.5 , 4. ]])
其中strategy参数用来选择代替缺失值方法:
mean
表示使用平均值代替缺失值median
表示使用中位数代替缺失值most_frequent
表示使用出现频率最多的值代替缺失值missing_values参数表示何为缺失值:
NaN
表示np.nan
为缺失值0
表示0
为缺失值