Python金融数据挖掘与分析实战
上QQ阅读APP看书,第一时间看更新

3.2.6 特征缩放

特征缩放(feature scaling)是数据预处理中非常重要的一环。比如我们想对某学校的优秀毕业生进行建模,试图了解学校评判标准,什么样的平时成绩和毕业考试成绩能够使学生大概率获得优秀毕业生荣誉(假设学校仅通过这两项特征进行考核)。目前收集到的数据包括近三届毕业生的平时成绩、毕业考试成绩以及是否获得优秀毕业生荣誉。我们发现,平时成绩满分是100分,毕业考试满分是740分,而建立线性关系时通常会将两者相加,两项成绩悬殊的尺度差距将导致两者变化时对合计数值的影响力相差颇多。所以在建模时,需要使用更多的计算资源调整模型。这时,就需要用到特征缩放。

特征缩放是一种将原始数据转变成相似尺度的数值。一般在面对多维特征的时候,我们要确定这些特征具有相似的尺度,如果尺度差异较大,就需要将原始数据进行中心化(zero-centered或mean-subtraction)处理和标准化(standardization或normalization)处理。原始数据经处理后,各特征的值处于同一数量级,适合进行综合对比评价。

使用支持向量机(Support Vector Machine,SVM)和K均值聚类算法时,特征缩放将非常有效。在使用梯度下降(gradient descent)算法时,特征缩放可以帮助梯度更快地收敛,从而减少运算时间。

图3-14是特征缩放的效果展示,其中,左侧是原始数据,中间是中心化后的数据,右侧为经过标准化的数据。

图3-14 特征缩放效果

图3-14 (续)

通常来说,特征缩放有四种常见形式。

(1)均值标准化(Z-Score Standardization)

均值标准化使每个特征的值具有零均值(zero-mean)和单位方差(unit-variance)。这个方法被广泛应用在支持向量机、逻辑回归和神经网络等机器学习算法中。公式如下:

代码如下:


from sklearn.preprocessing import StandardScaler
StandardScaler(copy=True,with_mean=True,with_std=True)
from sklearn.preprocessing import scale

(2)比例调节(rescaling)

比例调节又称Min-Max比例调节。这种方法是将数据的特征缩放到[0, 1]或者[-1, 1]的区间中。至于缩放到什么方位,则取决于数据的性质。公式如下:

代码如下:


from sklearn.preprocessing import MinMaxScaler

(3)均值归一化(Mean Normalization)

通过将每个x减去x的平均值,再除以测试集中x的取值范围,将特征x的平均值转换为0。公式如下:

(4)缩放到单位向量(Scaling to Unit Length)

公式如下:

代码如下:


from sklearn.preprocessing import Normalizer

比如有一组男性购买上衣外套的数据,我们希望通过身高、体重和腰围三个维度的数据来预测衣服尺码给新客户进行推荐,如表3-1所示。

表3-1 案例数据

注:1尺=33.33厘米。

不难发现三个维度的取值范围相差悬殊,男性身高通常为1.5~2米,体重通常为50~120公斤,腰围通常为2~3尺。

假设模型是将各维度数据相加且各项系数均为一,那么得到的第一个人尺码度量值(y1)为:

y1=1.85+88+2.8=92.65

第二个人尺码度量值(y2)为:

y2=1.72+68+2.4=72.12

第三个人尺码度量值(y3)为:

y3=1.81+76+2.7=80.51

假设外套尺码只有L和S两种情况,那么:

|92.65-80.51|=12.14>|72.12-80.51|=8.39

第三个人的度量值更为接近第二个人的度量值,得出推荐尺码为S码。

这个结果是因为体重这个特征的值通常比身高和腰围大很多,那么在系数均为1时,整体度量值是由体重主导的。不同的范围值导致机器学习过程中需要花费大量的计算资源,通过调整系数等手段平衡各特征维度在最终预测值中的权重。如果我们预先对数据范围进行处理,比如转换为0至1的取值范围,就可以避免这些浪费。虽然数值单位不再是原本的单位,但包含的信息并未遗漏,只是取值范围被缩小了。使用前文提到的第三种方法进行均值归一化处理,根据公式,得到表3-2所示的新数值。

|3-1.84|=1.16<|0-1.84|=1.84

表3-2 案例数据

通过归一化后的数据,我们发现应该推荐的外套尺码应为L。

不难看出,这种转换方法有一个明显缺陷,如果有新数据加入会使最大值和最小值发生变化,导致需要重新定义、重新计算。

继续以Income_n_onlineshopping为例,样本被分成训练集与测试集后:


# 特征缩放
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)
X_test = sc_X.transform(X_test)
X_train
array([[ 1.88982237,-0.84079776,  0.06129203],
       [ 0.37796447,-1.20769133,  0.47830697],
       [-1.13389342,-0.10701062,-0.95833241],
       [-1.13389342,-0.35160634,-1.37076476],
       [ 0.37796447,  1.97205293,  1.92869409],
       [-1.13389342,  1.23826579,-0.39467485],
       [ 0.37796447,-0.47390419,  0.85636996],
       [ 0.37796447,-0.22930848,-0.60089103]])