很多时候,如果不对数据进行统一化,会导致梯度下降复杂或是损失函数只能选择线性,导致模型效果不佳。
从经验上说,对特征值进行统一化是让不同维度之间的特征在数值上有一定比较性,可以大大提高分类器的准确性。
公式:(X-X_mean)/X_std 计算时对每个属性/每列分别进行, Z-score 标准化。
将数据按其属性(按列进行)减去其均值,然后除以其方差。最后得到的结果是,对每个属性/每列来说所有数据都聚集在0附近,方差值为1。
首先说明下sklearn中preprocessing库里面的scale函数使用方法,默认参数如下:
scale(X, axis=0, with_mean=True, with_std=True, copy=True)
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
[[ 0. -1.22474487 1.33630621]
[ 1.22474487 0. -0.26726124]
[-1.22474487 1.22474487 -1.06904497]]
print(X_scaled.mean(axis=0)) ### 计算X_scaled特征(每列)的均值进行验证
print(X_scaled.std(axis=0)) ### 计算X_scaled特征(每列)的方差进行验证
[ 0. 0. 0.]
[ 1. 1. 1.]
(X_train-X_train.mean(axis=0))/X_train.std(axis=0) ###用原始公式将X_train标准化,结果如下:
[[ 0. -1.22474487 1.33630621]
[ 1.22474487 0. -0.26726124]
[-1.22474487 1.22474487 -1.06904497]]
from sklearn.preprocessing import StandardScaler
scaler=StandardScaler().fit(X_train)
scaler
StandardScaler(copy=True, with_mean=True, with_std=True)
print(scaler.mean_)
[ 1. 0. 0.33333333]
print(scaler.scale_)
[ 0.81649658 0.81649658 1.24721913]
scaler.transform(X_train)
array([[ 0. , -1.22474487, 1.33630621], [ 1.22474487, 0. , -0.26726124], [-1.22474487, 1.22474487, -1.06904497]])
除了上述方法,还可以通过将数据特征值缩放到一个最大、最小区间之中【0,1】,可以用preprocessing.MinMaxScaler实现,默认参数如下:
MinMaxScaler
(feature_range=(0, 1), copy=True)### 若取值范围在[-1,1],则令feature_range=(-1,1)
公式: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
使用这种方法的目的包括:
from sklearn.preprocessing import MinMaxScaler
min_max_scaler=MinMaxScaler()
X_train_minmax=min_max_scaler.fit_transform(X_train)
X_train_minmax
array([[ 0.5 , 0. , 1. ], [ 1. , 0.5 , 0.33333333], [ 0. , 1. , 0. ]])
### 训练数据的特征标准化之后,可以通过transform实现对测试数据或新的数据标准化按照原来的标准化规则
X_test=np.array([[-3,-1,4]])
X_test_minmax=min_max_scaler.transform(X_test)
X_test_minmax
array([[-1.5 , 0. , 1.66666667]])
该过程是将每个样本缩放到单位范数(每个样本的范数为1),如果使用如二次型(点积)或者其它核方法计算两个样本之间的相似性这个方法会很有用。
该方法是文本分类和聚类分析中经常使用的向量空间模型(Vector Space Model)的基础.
Normalization主要思想是对每个样本计算其p-范数,然后对该样本中每个元素除以该范数,这样处理的结果是使得每个处理后样本的p-范数(l1-norm,l2-norm)等于1。
可以用preprocessing.normalize实现,该函数默认参数如下:
normalize
(X, norm=’l2’, axis=1, copy=True, return_norm=False)
norm='l2'时,每个样本的特征值为原始值除以各个特征值的模或绝对值和的平方
norm='l1'时,变换后变换后每个样本的各维特征的绝对值和为1。
方法1:
from sklearn.preprocessing import normalize
X = [[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]]
X_normalized=normalize(X)
X_normalized
[[ 0.40824829 -0.40824829 0.81649658] [ 1. 0. 0. ] [ 0. 0.70710678 -0.70710678]]
方法2:
from sklearn.preprocessing import Normalizer
X = [[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]]
normalizer = Normalizer().fit(X)
normalizer.transform(X)
[[ 0.40824829, -0.40824829, 0.81649658] [ 1. , 0. , 0. ] [ 0. , 0.70710678, -0.70710678]]
特征的二值化主要是为了将数据特征转变成boolean变量。在sklearn中,sklearn.preprocessing.Binarizer函数可以实现这一功能,该函数默认参数如下:
Binarizer
(threshold=0.0, copy=True) ###默认阈值为0,即特征值大于0为1,小于0为0.
from sklearn.preprocessing import Binarizer
X = [[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]]
Binarization=Binarizer().fit(X)
Binarization
Binarizer(copy=True, threshold=0.0)
Binarization.transform(X)
[[ 1. 0. 1.] [ 1. 0. 0.] [ 0. 1. 0.]]
由于不同的原因,许多现实中的数据集都包含有缺失值,要么是空白的,要么使用NaNs或者其它的符号替代。这些数据无法直接使用scikit-learn分类器直接训练,所以需要进行处理。幸运地是,sklearn中的Imputer类提供了一些基本的方法来处理缺失值,如使用均值、中位值或者缺失值所在列中频繁出现的值来替换。sklearn.preprocessing.Imputer可以实现,该函数默认参数如下:
Imputer
(missing_values=’NaN’, strategy=’mean’, axis=0, verbose=0,copy=True)
import numpy as np
from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
x=np.array([[1, 2], [np.nan, 3], [7, 6]])
imp.fit(X)
Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
imp.transform(X)
[[ 1. 2.] [ 4. 3.] [ 7. 6.]]
X1 = [[np.nan, 2], [6, np.nan], [7, 6]]
imp.transform(X1) ### 按照X数据每列的平均值填充X1中的空值,比如果X是训练数据,X1是测试数据,X1每列空值则是X每列平均值
array([[ 4. , 2. ], [ 6. , 3.66666667], [ 7. , 6. ]])
Imputer同样支持稀疏矩阵
import scipy.sparse as sp
X = sp.csc_matrix([[1, 2], [0, 3], [7, 6]])
imp = Imputer(missing_values=0, strategy='mean', axis=0)
imp.fit(X)
Imputer(axis=0, copy=True, missing_values=0, strategy='mean', verbose=0)
X_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]])
print(imp.transform(X_test))
[[ 4. 2. ]
[ 6. 3.666...]
[ 7. 6. ]]