Python数据预处理

标准化:数据的标准化(normalization)是将数据按比例缩放,使之落入一个小的特定区间。在某些比较和评价的指标处理中经常会用到,去除数据的单位限制,将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权。

标准化基于正态分布的假设,将数据变换为均值为0、标准差为1的标准正态分布。但即使数据不服从正态分布,也可以用此法。特别适用于数据的最大值和最小值未知,或存在孤立点。

主要方法:
z-score标准化,即零-均值标准化(常用方法)

$$y=\frac{x-μ}σ$$

~~~ 下面看看在Python中的实现

方法1.scale可以直接对数组进行标准化,请看下例:

1
2
3
4
5
import numpy as np
from sklearn import preprocessing
X_train=np.array([[1,50,500],[2,40,400],[5,55,666]])
X_scaled=preprocessing.scale(X_train,axis=0)#axis默认值就是0,所以也可以不写
print X_scaled #标准化后的数据
[[-0.98058068  0.26726124 -0.20054214]
 [-0.39223227 -1.33630621 -1.11209733]
 [ 1.37281295  1.06904497  1.31263947]]

咱们可以检验一下这个X_scaled的均值和方差

1
2
print X_scaled.mean(axis=0)#均值
print X_scaled.std(axis=0)#方差
[  7.40148683e-17  -2.96059473e-16   0.00000000e+00]
[ 1.  1.  1.]

注意这里的axis=0代表按行处理,也就是把行压缩,也就是对每一列进行标准化,常用!

方法2.from skelearn.preprocessing import StandardScaler

1
2
scaler = preprocessing.StandardScaler()
scaler
StandardScaler(copy=True, with_mean=True, with_std=True)
1
scaler.fit(X_train)
StandardScaler(copy=True, with_mean=True, with_std=True)
1
scaler.transform(X_train)
array([[-0.98058068,  0.26726124, -0.20054214],
       [-0.39223227, -1.33630621, -1.11209733],
       [ 1.37281295,  1.06904497,  1.31263947]])

以上是把fit和transform两步分开进行的,我们也可以直接一步完成,如下:

1
scaler.fit_transform(X_train)
array([[-0.98058068,  0.26726124, -0.20054214],
       [-0.39223227, -1.33630621, -1.11209733],
       [ 1.37281295,  1.06904497,  1.31263947]])

但是要注意,在实际的建模过程中,我们通常将数据集划分为训练数据集和测试数据集,这时候我们应该分两步进行,先fit训练数据集,并将其定义为一个变量,比如ss,然后用ss来transform训练数据集从而进行模型的拟合,之后在检验模型的拟合度时,首先也要对测试数据集进行transform,这是就要用之前fit好的ss来transform测试数据集了,当然,这里只针对于变量数据,不包括target

同样可以用均值和方差来进行验证:

1
2
print scaler.fit_transform(X_train).mean(axis=0)
print scaler.fit_transform(X_train).std(axis=0)
[  7.40148683e-17  -2.96059473e-16   0.00000000e+00]
[ 1.  1.  1.]

我们一般采用方法2,因为它可以保存训练集中的参数(均值、方差)直接使用其对象转换测试集数据.

其实,对数据进行标准化的数学方法不止上面这一个,还有以下几个:

  • 离差标准化

则是对原始数据的一个线性变换,公式如下:

$$y=\frac{x-x_{min}}{x_{max}-x_{min}}$$

这种方法有个缺陷就是当有新数据加入时,可能导致$x_{max}$和$x_{min}$的变化,需要重新定义。

下面来编程模拟实现一个实例:

1
2
3
import numpy as np
x=np.array([[1.5,8.8,2.3],[5.8,5.0,6.2],[7.2,8.3,9.6],[4.4,5.5,6.6]])
x
array([[ 1.5,  8.8,  2.3],
       [ 5.8,  5. ,  6.2],
       [ 7.2,  8.3,  9.6],
       [ 4.4,  5.5,  6.6]])
1
x.shape
(4, 3)
1
2
3
4
5
X_NEW=[]
for i in range(0,x.shape[1]):
x_new=(x[:,i]-min(x[:,i]))/(max(x[:,i])-min(x[:,i]))
print x_new
X_NEW.append(x_new)
[ 0.          0.75438596  1.          0.50877193]
[ 1.          0.          0.86842105  0.13157895]
[ 0.          0.53424658  1.          0.5890411 ]
1
np.array(X_NEW).transpose()#最终数据
array([[ 0.        ,  1.        ,  0.        ],
       [ 0.75438596,  0.        ,  0.53424658],
       [ 1.        ,  0.86842105,  1.        ],
       [ 0.50877193,  0.13157895,  0.5890411 ]])

当然,我们也可以直接调用sklearn中的MinMaxScaler()来实现上述功能:

1
2
3
from sklearn import preprocessing   
min_max_scaler = preprocessing.MinMaxScaler()
X_minMax = min_max_scaler.fit_transform(x)
1
X_minMax#最终数据
array([[ 0.        ,  1.        ,  0.        ],
       [ 0.75438596,  0.        ,  0.53424658],
       [ 1.        ,  0.86842105,  1.        ],
       [ 0.50877193,  0.13157895,  0.5890411 ]])

结果是一模一样的!

为了方便起见,我们今后就直接调用MinMaxScaler() 就好了.

离差标准化可以扩展一下,比如我们想要把数据映射到-1和1之间,那么就采用以下数学公式:

$$x_{new}=\frac{x-x_{mean}}{x_{max}-x_{min}}$$

编程模拟一下,直接对之前的代码做一些改动就可以了,如下:

1
2
import numpy as np
x=np.array([[1.0,2.2,3.3],[5.2,3.3,2.2],[1.3,2.5,6.8]])
1
2
3
4
5
X_NEW=[]
for i in range(x.shape[1]):
x_new=(x[:,i]-np.mean(x[:,i]))/(max(x[:,i])-min(x[:,i]))
print x_new
X_NEW.append(x_new)
[-0.56578947  0.18859649  0.43421053 -0.05701754]
[ 0.5        -0.5         0.36842105 -0.36842105]
[-0.53082192  0.00342466  0.46917808  0.05821918]
1
np.array(X_NEW).transpose()#最终数据
array([[-0.56578947,  0.5       , -0.53082192],
       [ 0.18859649, -0.5       ,  0.00342466],
       [ 0.43421053,  0.36842105,  0.46917808],
       [-0.05701754, -0.36842105,  0.05821918]])

***

以上都是些常用的数据标准化方法,还有一些不太常用的方法,比如:

  • 对数Logistic模式:

$$X_{new}=\frac{1}{1+e^{-X_{old}}}$$

得出的数都在0和1之间

最后来说一下数据正则化

正则化主要是用于解决过拟合,正则性衡量了函数光滑的程度,正则性越高,函数越光滑。(光滑衡量了函数的可导性,如果一个函数是光滑函数,则该函数无穷可导,即任意n阶可导).

采用正则化方法会自动削弱不重要的特征变量,自动从许多的特征变量中”提取“重要的特征变量,减小特征变量的数量级。这个方法非常有效,当我们有很多特征变量时,其中每一个变量都能对预测产生一点影响。我们可以有很多特征变量,其中每一个变量都是有用的,因此我们不希望把它们删掉,这就导致了正则化概念的发生。

看一下在sklearn中的调用方法

1
2
import numpy as np
from sklearn.preprocessing import normalize
1
2
x=np.array([[1,2,3],[4,5,6],[7,8,9]])
x
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
1
2
normalizer = preprocessing.Normalizer().fit(x)  # fit does nothing
normalizer
Normalizer(copy=True, norm='l2')
1
normalizer.transform(x)#最终结果
array([[ 0.26726124,  0.53452248,  0.80178373],
       [ 0.45584231,  0.56980288,  0.68376346],
       [ 0.50257071,  0.57436653,  0.64616234]])

今天就写到这儿吧,有时间继续,如果能帮到你,还请关注下微信公众号“我将在南极找寻你”,更多干货尽在其中!

参考:
https://blog.csdn.net/gshgsh1228/article/details/52199870/ 

https://www.jianshu.com/p/0d8bb02f98fb

凡希 wechat
喜欢所以热爱,坚持干货分享,欢迎订阅我的微信公众号
呐,请我吃辣条