说明:本文是《Python数据分析与数据化运营》中的“3.9 标准化,让运营数据落入相同的范围”。 -----------------------------下面是正文内容--------------------------
数据标准化是一个常用的数据预处理操作,目的是将不同规模和量纲的数据经过处理,缩放到相同的数据区间和范围,以减少规模、特征、分布差异等对模型的影响。除了用作模型计算,标准化后的数据还具有了直接计算并生成复合指标的意义,是加权指标的必要步骤。
3.9.1 实现中心化和正态分布的Z-Score
Z-Score标准化是基于原始数据的均值和标准差进行的标准化,假设原转换的数据为x,新数据为x',那么x'=(x-mean)/std,其中mean和std为x所在列的均值和标准差。
这种方法适合大多数类型的数据,也是很多工具的默认标准化方法。标准化之后的数据是以0为均值,方差为1的正态分布。但是Z-Score方法是一种中心化方法,会改变原有数据的分布结构,不适合用于对稀疏数据做处理。
提示 在很多时候,数据集会存在稀疏性特征,表现为标准差小、并有很多元素的值为0,最常见的稀疏数据集是用来做协同过滤的数据集,绝大部分的数据都是0,仅有少部分数据为1。对稀疏数据做标准化,不能采用中心化的方式,否则会破坏稀疏数据的结构。
3.9.2 实现归一化的Max-Min
Max-Min标准化方法是对原始数据进行线性变换,假设原转换的数据为x,新数据为x',那么x'=(x-min)/(max-min),其中min和max为x所在列的最小值和最大值。
这种标准化方法的适应性非常广泛,得到的数据会完全落入[0,1]区间内(Z-Score则没有类似区间),这种方法能使数据归一化而落到一定的区间内,同时还能较好的保持原有数据结构。
3.9.3 用于稀疏数据的MaxAbs
最大值绝对值标准化(MaxAbs)根据最大值的绝对值进行标准化,假设原转换的数据为x,新数据为x',那么x'=x/|max|,其中max为x所在列的最大值。
MaxAbs方法跟Max-Min用法类似,也是将数据落入一定区间,但该方法的数据区间为[-1,1]。MaxAbs也具有不破坏原有数据分布结构的特点,因此也可以用于稀疏数据,或者稀疏的CSR或CSC矩阵。
提示 CSR(Compressed Sparse Row,行压缩)和CSC(Compressed Sparse Column,列压缩)是稀疏矩阵的两种存储格式,这两种稀疏矩阵在scipy.sparse包中应用广泛。除了这两种格式之外,用于存储稀疏矩阵的格式还有COO、CSR、DIA、ELL、HYB等。
3.9.4 针对离群点的RobustScaler
某些情况下,假如数据集中有离群点,我们可以使用Z-Score进行标准化,但是标准化后的数据并不理想,因为异常点的特征往往在标准化之后便容易失去离群特征。
此时,可以使用RobustScaler针对离群点做标准化处理,该方法对数据中心化和数据的缩放鲁棒性有更强的参数控制。
3.9.5 代码实操:Python数据标准化处理
本示例中,将使用Numpy、sklearn进行标准化相关处理。源文件data6.txt位于“附件-chapter3”中,默认工作目录为“附件-chapter3”(如果不是,请cd切换到该目录下,否则会报“IOError: File data5.txt does not exist”)。 完整代码如下:
import numpy as np
from sklearn import preprocessing
import matplotlib.pyplot as plt
data = np.loadtxt('data6.txt', delimiter='\t') # 读取数据
# Z-Score标准化
zscore_scaler = preprocessing.StandardScaler() # 建立StandardScaler对象
data_scale_1 = zscore_scaler.fit_transform(data) # StandardScaler标准化处理
# Max-Min标准化
minmax_scaler = preprocessing.MinMaxScaler() # 建立MinMaxScaler模型对象
data_scale_2 = minmax_scaler.fit_transform(data) # MinMaxScaler标准化处理
# MaxAbsScaler标准化
maxabsscaler_scaler = preprocessing.MaxAbsScaler() # 建立MaxAbsScaler对象
data_scale_3 = maxabsscaler_scaler.fit_transform(data) # MaxAbsScaler标准化处理
# RobustScaler标准化
robustscalerr_scaler = preprocessing.RobustScaler() # 建立RobustScaler标准化对象
data_scale_4 = robustscalerr_scaler.fit_transform(data) # RobustScaler标准化标准化处理
# 展示多网格结果
data_list = [data, data_scale_1, data_scale_2, data_scale_3, data_scale_4] # 创建数据集列表
scalar_list = [15, 10, 15, 10, 15, 10] # 创建点尺寸列表
color_list = ['black', 'green', 'blue', 'yellow', 'red'] # 创建颜色列表
merker_list = ['o', ',', '+', 's', 'p'] # 创建样式列表
title_list = ['source data', 'zscore_scaler', 'minmax_scaler', 'maxabsscaler_scaler', 'robustscalerr_scaler'] # 创建标题列表
for i, data_single in enumerate(data_list): # 循环得到索引和每个数值
plt.subplot(2, 3, i + 1) # 确定子网格
plt.scatter(data_single[:, :-1], data_single[:, -1], s=scalar_list[i], marker=merker_list[i], c=color_list[i]) # 自网格展示散点图
plt.title(title_list[i]) # 设置自网格标题
plt.suptitle("raw data and standardized data") # 设置总标题
plt.show() # 展示图形
示例代码以空行分为7个部分。 第一部分导入库,示例中用到了Numpy做数据读取、sklearn中的preprocessing模块做标准化处理、matplotlib.pyplot模块做可视化图形展示。
第二部分使用Numpy的loadt方法导入数据文件,文件以tab分隔。
第三部分进行Z-Score标准化。通过preprocessing.StandardScaler建立模型,然后应用fit_transform方法进行转换。除了StandardScaler类外,还可直接使用preprocessing.scale(X)做标准化处理,二者的应用差别是preprocessing.StandardScaler方法既可以满足一次性的标准化处理,又能转换数据集的特征保存下来,分别通过fit和transform对多个数据集(例如测试集和训练集)做相同规则的转换。该方法针对训练集、测试集和应用集分别应用时非常有效。
第四部分进行Max-Min标准化。通过preprocessing.MinMaxScaler建立模型,然后应用fit_transform方法进行转换。其中的fit_transform方法都可以分别使用fit然后使用transform做多数据集的应用。该方法也可以使用没有面向对象API的等效函数sklearn.preprocessing.minmax_scale。
提示 在Python中,Max-Min标准化不仅能将数据落入[0, 1]的区间,还可以指定最大和最小值范围。通过在建立对象时设置preprocessing.MinMaxScaler(feature_range=(min,max))来自定义标准化后的数据区间。
第五部分进行MaxAbsScaler标准化。通过preprocessing.MaxAbsScaler建立模型,然后应用fit_transform方法进行转换,也可以使用没有面向对象API的等效函数sklearn.preprocessing.maxabs_scale。
第六部分进行RobustScaler标准化。通过preprocessing.RobustScaler建立模型,然后应用fit_transform方法进行转换,也可以使用没有面向对象API的等效函数sklearn.preprocessing.robust_scale。
第七部分展示原始数据和4种标准化的结果。在该部分功能中,将原始数据以及通过上述四种方法得到的结果数据统一对比展示。主要步骤如下:
- 先创建5个列表,用于存储原始数据和4个标准化后的数据、散点尺寸、颜色、样式、标题。
- 通过for循环结合enumerate将索引值和5份数据循环读出;通过plt.subplot为不同的数据设置不同的网格,该网格为2行3列;在每个网格中通过plt.scatter画出散点图,并通过索引来讲列表中对应的值作为参数传给scatter;然后通过title方法每个子网格设置标题。
- 最后设置整个图像的总标题并展示图像
上述过程中,主要需要考虑的关键点是如何根据不同的数据分布特征和应用选择合适的标准化方式:
- 如果要做中心化处理,并且对数据分布有正态需求,那么使用Z-Score方法;
- 如果要进行0-1标准化或将要指定标准化后的数据分布范围,那么使用Max-Min标准化或MaxAbs标准化方式是比较好的选择,尤其是前者;
- 如果要对稀疏数据进行处理,Max-Min标准化或MaxAbs标准化仍然是理想方法;
- 如果要最大限度的保留数据集中的异常,那么使用RobustScaler方法更加。
代码实操小结:本小节示例中,主要用了几个知识点:
- 通过Numpy的loadtxt方法读取文本数据文件,并指定分隔符
- 使用sklearn.preprocessing的StandardScaler方法做Z-Score标准化处理
- 使用sklearn.preprocessing的MinMaxScaler方法做Max-Min标准化处理
- 使用sklearn.preprocessing的MaxAbsScaler方法做最大值绝对值标准化处理
- 使用sklearn.preprocessing的RobustScaler方法做针对异常数据的处理
- 通过matplotlib.pyplot画图,并在一幅大图中设置使用subplot设置多个子网格,使用scatter画出散点图并设置颜色、样式、大小,使用title和suptitle设置子网格和整体图像标题并最终通过show方法展示图像