通过将属性值按比例缩放,使之落入一个小的特定区间,如0.0~1.0,对属性规范化。有很多数据规范化的方法,这里我们将介绍三种:最小--最大规范化,z-score规范化,按小数定标规范化和最大绝对值缩放。
下面简单介绍着几种规范化的原理:
最小--最大规范化对原始数据进行线性变换。假定minA和maxA分别是属性A的最小值和最大值。最小--最大规范化通过计算:
v' = (v - min) /(max - min )* (new_max - new_min) + new_min
这样可以将A的值映射到区间[new_min , new_max]中的v'。
又称为零均值 规范化,将属性A的值基于均值和方差规范化,在不知道属性A的最小值和最大值的时候,或者是离群值左右了最小--最大规范化时,该方法是有用的。
v' = v - mean / std
通过移动属性A的小数点位置进行规范化,小数点的移动位数依赖于A的最大绝对值,由下式计算:
v' = v / 10^j
其中j是使得Max(| v' |) <1的最小整数。
例如:假定属性A的取值范围是-986 ~ 917。A的最大绝对值为986.使用小数定标规范化,用1000(即j = 3)除每个数,这样,-986就会被规范化为-0.986,而917也会被规范化成-0.917.
它只通过除以每个特征的最大值将训练数据特征缩放至 [-1, 1]。这就意味着,训练数据应该是已经零中
心化或者是稀疏数据。
from sklearn import preprocessing
import numpy as np
X = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
X_scaled = preprocessing.scale(X) #对每一列的值进行标准化
X_scaled
Out[622]:
array([[ 0. , -1.22474487, 1.33630621],
[ 1.22474487, 0. , -0.26726124],
[-1.22474487, 1.22474487, -1.06904497]])
X_scaled.mean(axis=0) #标准化后数据的均值为0.方差为1
Out[623]: array([0., 0., 0.])
X_scaled.std(axis=0)
Out[624]: array([1., 1., 1.])
preprocessing``模块也提供了一个实用类:class:`StandardScaler` ,它使用 ``Transformer 接口在训练集上计算均值和标准差,以便于在后续的测试集上进行相同的缩放.
scaler = preprocessing.StandardScaler().fit(X)
scaler
Out[626]: StandardScaler(copy=True, with_mean=True, with_std=True)
scaler.mean_
Out[627]: array([1. , 0. , 0.33333333])
scaler.scale_
Out[628]: array([0.81649658, 0.81649658, 1.24721913])
scaler.transform(X) #计算均值和标准差
Out[629]:
array([[ 0. , -1.22474487, 1.33630621],
[ 1.22474487, 0. , -0.26726124],
[-1.22474487, 1.22474487, -1.06904497]])
#缩放类对象可以在新的数据上实现和训练集相同缩放操作:
scaler.transform([[-1., 1., 0.]])
Out[631]: array([[-2.44948974, 1.22474487, -0.26726124]])
另外一个可选的缩放操作是将特征缩放至给定的最小、最大值范围,经常是[0,1]。 或者也可以将每个特征的最大绝对值转换至单位大小。这两类操作可以分别通过使用:class:`MinMaxScaler`或者:class:`MaxAbsScaler`实现。
使用这种方法的目的包括:
1、对于方差非常小的属性可以增强其稳定性。
2、维持稀疏矩阵中为0的条目。
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train) #使用最小--最大规范化对原始数据进行规范化,默认映射到[0,1]
X_train_minmax
Out[677]:
array([[0.5 , 0. , 1. ],
[1. , 0.5 , 0.33333333],
[0. , 1. , 0. ]])
#同样的转换实例可以被用与在训练过程中不可见的测试数据:实现和训练数据一致的缩放和移位操作:
X_test = np.array([[ -3., -1., 4.]])
X_test_minmax = min_max_scaler.transform(X_test)
X_test_minmax
Out[681]: array([[-1.5 , 0. , 1.66666667]])
##你也可以通过查看缩放器(scaler)的属性,来观察在训练集中学习到的转换操作的基本性质:
min_max_scaler.scale_
Out[683]: array([0.5 , 0.5 , 0.33333333])
min_max_scaler.min_
Out[684]: array([0. , 0.5 , 0.33333333])
#如果:class:MinMaxScaler`被提供了一个精确的``feature_range=(min, max)`,完整的公式是:
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_scaled = X_std * (max - min) + min
###自定义缩放的范围
min_max_scaler = preprocessing.MinMaxScaler(feature_range=(1, 2))
X_train_minmax = min_max_scaler.fit_transform(X_train)
X_train_minmax
Out[689]:
array([[1.5 , 1. , 2. ],
[2. , 1.5 , 1.33333333],
[1. , 2. , 1. ]])
MaxAbsScaler 工作原理非常相似,但是它只通过除以每个特征的最大值将训练数据特征缩放至 [-1, 1]。这就意味着,训练数据应该是已经零中心化或者是稀疏数据。 例子::用先前例子的数据实现最大绝对值缩放操作:
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
max_abs_scaler = preprocessing.MaxAbsScaler()
X_train_maxabs = max_abs_scaler.fit_transform(X_train)
X_train_maxabs # doctest +NORMALIZE_WHITESPACE^
Out[693]:
array([[ 0.5, -1. , 1. ],
[ 1. , 0. , 0. ],
[ 0. , 1. , -0.5]])
X_test = np.array([[ -3., -1., 4.]])
X_test_maxabs = max_abs_scaler.transform(X_test)
X_test_maxabs
Out[696]: array([[-1.5, -1. , 2. ]])
max_abs_scaler.scale_
Out[697]: array([2., 1., 2.])
正则化的过程是将每个样本缩放到单位范数(每个样本点的范数为1),如果后面要使用如二次型(点积)或者其他和方法计算两个样本之间的相似性,这个方法会很有用。
Normalization主要思想是对每个样本计算其P-范数,然后对该样本中每个元素初一该范数,这样处理的结果是使得每个处理后的样本的p-范数(|1 - norm|,|2 - norm|)等于1.
p-范数的计算公式:||X||p=(|x1|^p+|x2|^p+...+|xn|^p)^1/p
该方法主要应用于文本分类和聚类中。例如,对于两个TF-IDF向量的I2-norm进行点积,就可以得到这两个向量的余弦相似性。
方法1:使用sklearn.preprocessing.normalize()函数
X = [[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]]
X_normalized = preprocessing.normalize(X, norm='l2')
X_normalized
Out[700]:
array([[ 0.40824829, -0.40824829, 0.81649658],
[ 1. , 0. , 0. ],
[ 0. , 0.70710678, -0.70710678]])
方法2:sklearn.preprocessing.StandardScaler类
normalizer = preprocessing.Normalizer().fit(X) # fit函数没有任何效果
normalizer
Out[702]: Normalizer(copy=True, norm='l2')
normalizer.transform(X)
Out[703]:
array([[ 0.40824829, -0.40824829, 0.81649658],
[ 1. , 0. , 0. ],
[ 0. , 0.70710678, -0.70710678]])
normalizer.transform([[-1., 1., 0.]])
Out[704]: array([[-0.70710678, 0.70710678, 0. ]])
特征的二值化主要是为了将数据特征转变成boolean变量。在sklearn中,sklearn.preprocessing.Binarizer函数可以实现这一功能。实例如下:
X = [[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]]
binarizer = preprocessing.Binarizer().fit(X) # fit does nothing
binarizer
Out[707]: Binarizer(copy=True, threshold=0.0)
binarizer.transform(X)
Out[708]:
array([[1., 0., 1.],
[1., 0., 0.],
[0., 1., 0.]])
##可以改变二值器的阈值:
binarizer = preprocessing.Binarizer(threshold=1.1)
binarizer.transform(X)
Out[710]:
array([[0., 0., 1.],
[1., 0., 0.],
[0., 0., 0.]])
在很多时候变量的取值是分类数据,而不是连续的数值特征,比如一个人的性别可以是["male","female"],["from Europe","from US","from Asia"], ["user Firefox","use Chrome","user Internet Explorer"]这样的编码,例如["male" . "from US", "use Internet Explorer"]可以表示成[0, 1, 3]
这样的整数特征并不能在scikit - learn中直接使用,因为这样连续的输入,solve会认为类别之间是有序的,但实际上是无序的。(就好像浏览器的类别数据是无序的)
可以将类别特征转换成scikit - learn估计其可以使用的特征的方法有one - of - k或者one - hot编码,该方法是:class:OneHotEncoder`的一个实现。该方法将每个类别特征的 ``m` 可能值转换成``m``个二进制特征值,当然只有一个是激活值。
enc = preprocessing.OneHotEncoder()
enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
Out[712]:
OneHotEncoder(categorical_features='all', dtype=,
handle_unknown='error', n_values='auto', sparse=True)
enc.transform([[0, 1, 3]]).toarray()
Out[713]: array([[1., 0., 0., 1., 0., 0., 0., 0., 1.]])
默认情况下,每个特征使用几维的数值由数据集自动推断。当然,你也可以通过使用参数``n_values``来精确指定。 在我们的例 子数据集中,有两个可能得性别类别,三个洲,四个网络浏览器。接着,我们训练编码算法,并用来对一个样本数据进行转换。 在结果中,前两个数值是性别编码,紧接着的三个数值是洲编码,最后的四个数值是浏览器编码。