很多机器学习的方法都要求数据近似正态分布并尽可能接近,而python中用于机器学习的包便是sklearn,其提供包括MinMaxScaler,RobustScaler,StandardScaler和Normalizer在内的多种函数用于机器学习的预处理,那么这些方法应该如何选择呢?首先我们介绍下区别然后采用实际数据进行处理查看数据处理前后的变化,最后再来做一个总结.

定义

scale: 通常意味着更改值的范围,而保持分布的形状不会发生改变.就跟实物和模型一样,这就是为什么我们说它是按比例变化的。 该范围通常设置为 0 到 1。 standardize: 标准化通常更改数值使得分布的标准差等于1。 normalize: 该表达可用于上述两种处理,因此为防止混淆,应避免使用.

原因

那么为什么要进行标准化与归一化呢?

这是因为多种算法在处理标准化或者归一话后的数值时速度更快.比如:

  • 线性回归
  • KNN
  • NN
  • SVM
  • PCA
  • LDA

生成测试数据

数据生成使用np.random下的函数生成,这里分别生成beta分布,exponential分布,正态分布以及中心和范围变化的正态分布.代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 设置种子,保证数据可重现
np.random.seed(1024)
data_beta = np.random.beta(1,2,1000)
data_exp = np.random.exponential(scale=2,size=1000)
data_nor = np.random.normal(loc=1,scale=2,size=1000)
data_bignor = np.random.normal(loc=2,scale=5,size=1000)
# 生成dataframe
df = pd.DataFrame({"beta":data_beta,"exp":data_exp,"bignor":data_bignor,"nor":data_nor})
df.head()
# 	beta	exp	bignor	nor
# 0	0.383949	1.115062	5.681630	3.384865
# 1	0.328885	0.831677	7.175799	3.036709
# 2	0.048446	8.407472	4.119069	-2.049115
# 3	0.108803	8.125079	10.164492	1.026024
# 4	0.376316	2.721583	6.848210	3.390942

查看该数据集的分布曲线

sns.displot(df.melt(),x="value",hue="variable",kind="kde")
plt.savefig("origin.png",dpi=200)

origin

比较不同处理后数据变化情况

分别使用MinMaxScaler,RobustScaler和StandardScaler进行处理并比较

MinMaxScaler

from sklearn.preprocessing import MinMaxScaler
df_minmax = pd.DataFrame(MinMaxScaler().fit(df).transform(df), columns = df.columns)
sns.displot(df_minmax.melt(),x="value",hue="variable",kind="kde")
plt.savefig("minmaxscaler.png",dpi=200)
plt.close()

MinMaxScaler转换后数据变成这样


beta	exp	bignor	nor
0	0.402556	0.077887	0.623988	0.662302
1	0.344735	0.058066	0.671804	0.635879
2	0.050261	0.587947	0.573984	0.249901
3	0.113638	0.568196	0.767447	0.483282
4	0.394540	0.190253	0.661321	0.662763

分布为 minmaxscaler

RobustScaler

from sklearn.preprocessing import RobustScaler
df_rsca = pd.DataFrame(RobustScaler().fit(df).transform(df), columns = df.columns)
sns.displot(df_rsca.melt(),x="value",hue="variable",kind="kde")
plt.savefig("robustscaler.png",dpi=200)
plt.close()

RobustScaler转换后数据变成这样

	beta	exp	bignor	nor
0	0.284395	-0.141315	0.551292	0.923234
1	0.126973	-0.278467	0.779068	0.790394
2	-0.674763	3.388036	0.313090	-1.150118
3	-0.502211	3.251365	1.234674	0.023211
4	0.262573	0.636202	0.729129	0.925553

分布为 robustscaler

StandardScaler

from sklearn.preprocessing import  StandardScaler
df_std = pd.DataFrame(StandardScaler().fit(df).transform(df), columns = df.columns)
sns.displot(df_std.melt(),x="value",hue="variable",kind="kde")
plt.savefig("standardscaler.png",dpi=200)
plt.close()

StandardScaler转换后数据变成这样

	beta	exp	bignor	nor
0	0.252859	-0.460413	0.711804	1.207845
1	0.012554	-0.600899	1.008364	1.030065
2	-1.211305	3.154733	0.401670	-1.566938
3	-0.947902	3.014740	1.601554	0.003337
4	0.219547	0.336005	0.943345	1.210949

分布为 standardscaler

总结

该文中总结了多种标准化与归一化的方法,使用这些方法的好处以及它们对数据分布的影响,一般来说,使用standardize标准化是比较常见的做法.