( X − X m i n ) ( X m a x − X m i n ) (X-X_{min})\over(X_{max}-X_{min}) (Xmax−Xmin)(X−Xmin)
此处量纲简单理解,由于数据的不同单位出现的不同表现力,即单位
( X − X m e a n ) ( X s t d ) (X-X_{mean})\over(X_{std}) (Xstd)(X−Xmean)
def __init__(self, copy=True, with_mean=True, with_std=True)
patial_fit
增加X_scaled = preprocessing.StandardScaler().fit_transform(X_train)
X_scaled = preprocessing.StandardScaler().fit(X_train).transform(X_train)
以上两句代码是等价的,其目的都是首先构造一个数据标准化转换器,之后用需要标准化的数据训练转换器以拟合数据,最后实现标准化。
在函数 fit_transform
中,其实调用的是就是fit(X_train).transform(X_train)
if y is None:
# fit method of arity 1 (unsupervised transformation)
return self.fit(X, **fit_params).transform(X)
else:
# fit method of arity 2 (supervised transformation)
return self.fit(X, y, **fit_params).transform(X)
fit()
的实际实现函数,计算平均值和标准差。适合X作为连续的数据流输入X_scaled = preprocessing.StandardScaler().fit(X_train).transform(X_train)
X_scaled
array([[ 0. , -1.22474487, 1.33630621],
[ 1.22474487, 0. , -0.26726124],
[-1.22474487, 1.22474487, -1.06904497]])
X_scaled = preprocessing.StandardScaler().fit_transform(X_train)
X_scaled
array([[ 0. , -1.22474487, 1.33630621],
[ 1.22474487, 0. , -0.26726124],
[-1.22474487, 1.22474487, -1.06904497]])
构造StandardScaler对象的实际意义在于它首先通过执行转换器的API计算测试集数据的均值和标准差,之后便可用该构造器对测试集数据进行转换。
scaler = preprocessing.StandardScaler().fit(X_train) # 用训练集数据训练scaler
X_scaled = scaler.transform(X_train) # 用其转换训练集是理所当然的
X_scaled
array([[ 0. , -1.22474487, 1.33630621],
[ 1.22474487, 0. , -0.26726124],
[-1.22474487, 1.22474487, -1.06904497]])
然而实际上,用训练好的转换器去转换测试集数据也是可以的
# scaler.mean_ = [1. , 0. , 0.33333333]
# scaler.scale_ = [0.81649658, 0.81649658, 1.24721913]
X_test = [[-1., 1., 0.]]
X_test_scaled = scaler.transform(X_test)
# [-2.44948974, 1.22474487, -0.26726124]]
上述 X_test_scaled 是 scaler 利用前面测试集的数据得到的均值与标准差完成对测试集数据的标准化,可见它只是简单的对每个特征进行计算。
preprocessing.scale
函数def scale(X, axis=0, with_mean=True, with_std=True, copy=True)
X_train = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
x_scale = preprocessing.scale(X_train)
out:
x_scale
array([[ 0. , -1.22474487, 1.33630621],
[ 1.22474487, 0. , -0.26726124],
[-1.22474487, 1.22474487, -1.06904497]])
# 均值
x_scaled.mean(axis=0)
array([ 0., 0., 0.])
# 标准差
x_scaled.std(axis=0)
array([ 1., 1., 1.])
可见数据已经缩放为标准化,其特征均值为0,标准差为1,该函数的实现方式是对每个特征,即每一列按如下公式计算:
( X − X m e a n ) ( X s t d ) (X-X_{mean})\over(X_{std}) (Xstd)(X−Xmean)
def __init__(self, feature_range=(0, 1), copy=True)
参数说明
feature_range : 特征范围,指定标准化后的数据需要落在的范围,默认设定为[0,1]
if feature_range[0] >= feature_range[1]:
raise ValueError("Minimum of desired feature range must be smaller"
" than maximum. Got %s." % str(feature_range))
copy :一个可选的boolean类型值参数,默认为True,
常见属性说明
类主要函数
min_max_scaled = preprocessing.MinMaxScaler().fit_transform(X_train)
min_max_scaled = preprocessing.MinMaxScaler().fit(X_train).transform(X_train)
以上两句代码是等价的,其目的都是首先构造一个数据标准化转换器,之后用需要标准化的数据训练转换器以拟合数据,最后实现标准化。
fit()
的实际实现函数,计算用于以后缩放的最大值与最小值。适合X作为连续的数据流输入X_train = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
min_max_scaled = preprocessing.MinMaxScaler().fit_transform(X_train)
min_max_scaled
array([[0.5 , 0. , 1. ],
[1. , 0.5 , 0.33333333],
[0. , 1. , 0. ]])
实际上,类似于 z-score 标准化,min-max 标准化也有单独的一个简单函数可以实现而不是必须构建 MinMaxScaler 类。minmax-scale 函数的参数与 MinMaxScaler 类的参数一致,实现功能也是一致。
实际上,不得不说的一点是,minmax-scale 函数本质上是构造 MinMaxScaler 对象并调用 fit_transform 函数
s = MinMaxScaler(feature_range=feature_range, copy=copy)
if axis == 0:
X = s.fit_transform(X)
else:
X = s.fit_transform(X.T).T
MaxAbsScaler 类的工作原理与MinMaxScaler十分相似,它的功能是将数据缩放到[-1,1]之间。但 preprocessing.MinMaxScaler(feature_range=(-1,1)).fit_transform(X_train)
与preprocessing.MaxAbsScaler().fit_transform(X_train)
所得到的结果并不一致
X_train
array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
preprocessing.MaxAbsScaler().fit_transform(X_train)
array([[ 0.5, -1. , 1. ],
[ 1. , 0. , 0. ],
[ 0. , 1. , -0.5]])
preprocessing.MinMaxScaler(feature_range=(-1,1)).fit_transform(X_train)
array([[ 0. , -1. , 1. ],
[ 1. , 0. , -0.33333333],
[-1. , 1. , -1. ]])
原因是MinMaxScaler 实际操作是将数据集中每个数据除以该列特征中的最大值,以此实现最大绝对值缩放操作,并不是线性的。但 MinMaxScaler 却是需要线性变换,其相对变换比例一致。
Tips:拓展
在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;
与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。
稠密度:非零元素的总数比上矩阵所有元素的总数
对稀疏矩阵数据的缩放,maxabs_scale 函数与 MaxAbsScaler 类均可实现,不过前提是,训练数据应该是已经零中心化或者是稀疏数据。
Tips:数据中心化
使数据特征转换为均值为0的数据,称之为中心化。本质是将特征中每个数据减去该特征的均值
MaxAbsScaler 类以及 maxabs_scale 函数的功能十分简单,将每个元素除以该列特征中的最大值,因此它们的可选参数只有一个,不同的是,函数将原数据对象作为参数,而在转换器中,元数据是转换器调用链的其中一个环节的参数。
copy :boolean类型,默认为True,其含义即是否对原数据对象进行修改。
实际上,不得不说的一点是,maxabs_scale 函数本质上是构造 MaxAbsScaler 对象并调用 fit_transform 函数
s = MaxAbsScaler(copy=copy)
if axis == 0:
X = s.fit_transform(X)
else:
X = s.fit_transform(X.T).T
Tips:拓展
离群值:在数据中有一个或几个数值与其他数值相比差异较大,定量描述则是,如果一个数值偏离观测平均值的概率小于等于1/(2n),则该数据应当舍弃(其中n为观察例数,概率可以很据数据的分布进行估计)
对存在离群值数据的缩放,robust_scale 函数以及 RobustScaler 类均可实现
def __init__(self, with_centering=True, with_scaling=True,
quantile_range=(25.0, 75.0), copy=True):
参数说明
with_centering :默认为True
# 第一步,位于fit()函数
if self.with_centering:
self.center_ = np.nanmedian(X, axis=0)
# 第二步,位于transform()函数
if self.with_centering:
X -= self.center_
if self.with_centering:
if sparse.issparse(X):
raise ValueError(
"Cannot center sparse matrices: use `with_centering=False`"
" instead. See docstring for motivation and alternatives.")
with_scaling :默认为True
# 第一步,位于fit()函数
for feature_idx in range(X.shape[1]):
quantiles.append(np.nanpercentile(column_data,self.quantile_range))
# 第一步,位于fit()函数
quantiles = np.transpose(quantiles)
self.scale_ = quantiles[1] - quantiles[0]
# 第三步,位于fit()函数
self.scale_ = _handle_zeros_in_scale(self.scale_, copy=False)
# 第四步,位于transform()函数
if self.with_scaling:
X /= self.scale_
quantile_range:指定百分位值的位置,一个二元数组,默认是[25.0,75.0]
copy :略(与前面相同)
属性说明
基本例子
X = [[1., -2., 2.],
[-2., 1., 3.],
[4., 1., -2.]]
transformer = RobustScaler().fit_transform(X)
transformer
array([[ 0. , -2. , 0. ],
[-1. , 0. , 0.4],
[ 1. , 0. , -1.6]])
通过使用sklearn.decomposition.PCA 并设定whiten=True 移除特征间的线性关联
实现的功能与RobustScaler 类一样的功能,robust_scale 函数本质上是构造 RobustScaler 对象并调用 fit_transform 函数
s = RobustScaler(with_centering=with_centering, with_scaling=with_scaling,
quantile_range=quantile_range, copy=copy)
if axis == 0:
X = s.fit_transform(X)
else:
X = s.fit_transform(X.T).T
设K(x,z)是由phi(x)^ T phi(z)定义的核矩阵,其中phi是将x映射到希尔伯特空间的函数。
KernelCenterer 类构造过程中不需要设定任何参数,只在 fit 过程中需要传入核矩阵,之后进行转换。实质上,KernelCenterer 中心化数据的过程就是将数据集转换为零均值的归一化过程。但却不明确地计算phi(x)。可以认为它是使用sklearn.preprocessing.StandardScaler(with_std=False) 将 phi(x) 居中。