机器学习中的特征工程(二)---- 数值类型数据处理

简介

在介绍比较复杂的数据类型比如图像和文本数据类似之前,我们首先从最简单的数据类似开始,即:数值类型。我们收集到的数据中,数值类型数据占据了大部分。比如商品价格、人口数量、物品编号、传感器的数据、交通流量等等,几乎都是数值类型。数值类型数据可以直接输入到大部分模型中,但是这并不意味着对于数值类型的特征工程就不重要,好的特征提取方式是可以深挖隐藏在数据背后更深层次的信息的。其次,数值类型数据也并不是直观看上去那么简单易用,因为不同的数值类型的计量单位不一样,比如个数、公里、千克、DB、百分比之类,同样数值的大小也可能横跨好几个量级,比如小到头发丝直径约为0.00004米, 大到热门视频播放次数成千上万次。那么如何处理数值类型数据量纲以及分布的差异呢?这便是本文要重点讨论的地方。

数据尺度

输入数据的尺度差异是我们需要首先关注的问题,因为输入变量的尺度差异可能会增加模型拟合的困难程度。我们一般需要考虑输入数据中的最大值是多少?最小值是多少?它们之间差了几个数量级?这些问题很重要,因为某些模型对数据的尺度很敏感。举个例子,3x + 1是一个简单的线性模型,其输出直接依赖于输入变量x,很显然,输入x越大,输出也就越大。
较大的输入会导致模型学习到更大的权重参数,而具有较大参数的模型通常是不稳定的,一般会导致较大的泛化误差,这也就是为什么训练的时候一般需要加正则化的原因之一。输入数据尺度之间的差异也并不是会影响到所有的模型,一般来说,利用输出数据的权重和来拟合模型的算法一般会受到影响,比如线性回归,逻辑回归以及深度神经网络。同样,计算样本之间距离的算法也会收到影响,比如KNN算法、SVM等等。但是对于决策树模型则并不适用,以C4.5为例,决策树在进行节点分裂时主要依据数据集D关于特征x的信息增益比,而信息增益比跟特征的尺度是无关的。
上面只是讨论了输入数据的尺度对输出的影响,实际上目标值的尺度也会一定程度上影响模型整体的性能,尤其是在深度神经网络中更加明显。具有大范围值的目标标量可能会导致更大的误差梯度值,这会导致神经网络在反向传播时候梯度发生剧烈的变化,从而导致权重更新的也会比较剧烈,使得网络学习很不稳定。因此在深度神经网络中,对输入值和目标值的尺度缩放也非常关键。

数据归一化

数据归一化操作是指将特征的数据都统一到一个大致相同的数值区间(比如0~1)内。其目的是为了消除数据特征之间的量纲影响。归一化操作的前提是你可以准确估计数据的最大最小值。归一化的公式如下:

归一化
即按照占比将原始数据映射到0~1的范围之内,下图演示了这一过程。
归一化过程
Sklearn库中提供了相应的函数MinMaxScaler专门来做这种处理,我们来实践一下:

import numpy as np 
from sklearn.preprocessing import MinMaxScaler

#define data 
data = np.asarray([[100, 0.001], 
                   [8, 0.05], 
                   [50, 0.005], 
                   [88, 0.07], 
                   [4, 0.1]])
# define min max scaler
scaler = MinMaxScaler()
# transform data
scaled = scaler.fit_transform(data) 
print("scaled data:\n", scaled)
结果

注意这里的MinMaxScaler是应用在每一列数据上的。

数据标准化

数据标准化是指通过改变数据的分布得到均值为0,标准差为1的服从标准正态分布的数据。主要目的是为了让不同特征之间具有相同的尺度(Scale),这样更有理化模型训练收敛。总之,当原始数据不同维度上的特征尺度不一致时,需要标准化步骤对数据进行预处理。下图展示了原始数据、中心化后的数据、标准化后的数据的差异:

对比图

标准化的计算方式如下:
标准化计算公式
数据标准化处理的示意图如下:
同理,sklearn中内置了相应的StandardScaler函数来帮助我们对数据进行标准化处理。还是以上面的数据为例,代码如下:

from sklearn.preprocessing import StandardScaler

# define standard scaler
scaler = StandardScaler()
# transform data
scaled = scaler.fit_transform(data) 
print(scaled)
标准化

L1、L2规范化

规范化的过程就是将每个样本缩放到单位范数,主要思想是对每个样本计算其p-范数,然后将该样本每个元素除以该范数。L1、L2规范化其实就是L1、L2范数。L2归一化的具体计算公式如下:

其中||x||等于:
如果是L1范数的haunches,只需要把平方改成绝对值即可。L2规范化的示意图:
同理Sklearn中也有相应函数可以使用,例子如下:

from sklearn.preprocessing import normalize

#define data 
data = np.asarray([[ 1., -1.,  2.],
                   [ 2.,  0.,  0.],
                   [ 0.,  1., -1.]
                  ])

l1 = normalize(data, norm='l1')
print(l1)
l2 = normalize(data, norm='l2')
print(l2)
结果

对数转换

log函数的定义为log_a(\alpha^x) = x,其中a是log函数的底数,\alpha是一个正常数,x可以是任何正数。由于\alpha^0 = 1,我们有log_a(1) = 0。这意味着log函数可以将一些介于0~1之间小范围的数字映射到(-\infty, 0)范围内。比如当a=10时,函数log_{10}(x)可以将[1,10]映射到[0,1],将[1,100]映射到[1,2]。换句话说,log函数压缩了大数的范围,扩大了小数的范围。x越大,log(x)增量越慢。log(x)函数的图像如下:

对数函数图像
log函数主要是用于处理具有长尾分布的正数的有力工具。(长尾分布在尾部范围内的概率比高斯分布的概率大)。对数值类型使用对数转换一般有以下几种好处:

  • 缩小数据的绝对数值,方便计算
    比如,每个数据项都非常大,许多这样的值可能超过常用数据类型的最大值,取对数可以将这些数据都放缩到一定范围之内,方便计算。
  • 取对数后,可以将乘法计算转换成加法计算
  • 某些情况下,在数据的整个值域中不同区间的差异带来的影响不同
    数值小的部分差异的敏感程度比数值大的差异敏感程度更高。比如对于价格这个特征来说,如果你买家电,价格差几百块可能会影响你做决策。但是如果你买汽车,差了几百块你也会忽略不计了。
  • 取对数后不会改变数据的性质和相关关系,但压缩了变量的尺度。
  • 得到的数据易消除异方差问题

下面用一个例子来说明使用对数转换之后对数据的影响,使用的是Online News Popularity dataset数据集,我们取其中文章字数这一特征,来对其做对数转换。代码如下:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("./OnlineNewsPopularity.csv")
df['log_n_tokens_content'] = np.log10(df[' n_tokens_content'] + 1)

fig2, (ax1, ax2) = plt.subplots(2,1)
ax1.scatter(df[' n_tokens_content'], df[' shares'])
ax1.tick_params(labelsize=14)
ax1.set_xlabel('Number of Words in Article', fontsize=14)
ax1.set_ylabel('Number of Shares', fontsize=14)
ax2.scatter(df['log_n_tokens_content'], df[' shares'])
ax2.tick_params(labelsize=14)
ax2.set_xlabel('Log of the Number of Words in Article', fontsize=14)
ax2.set_ylabel('Number of Shares', fontsize=14)
对数转换前后对比

两张图对比可以发现,在未使用对数转换之前,即使输入数据之间的变化很小,但是对应的目标值变化很剧烈,这造成模型很难去拟合这种强烈的变化。使用对数转换之后,可以发现数据变得更加集中,输入对应的输出变化相对来说没有那么大。
Log函数可以极大压缩数值的范围,相对而言就扩展了小数字的范围。该转换方法适用于长尾分布且值域范围很大的特征,变换后的特征趋向于正态分布。

鲁棒归一化

有的时候,不可避免地,我们的输入数据中会出现一些离群值。这些处于分布边缘的值,出现的频率也很低,但是由于一般是较大或者较小的值,如果不作处理,可能会被模型当做特征学习进去。异常离群值通常会使概率分布倾斜,并且使得数据标准化处理变得困难,因为由于离群值的出现,会使得均值和标准差的计算出现倾斜。
在离群值存在的情况下,我们可以使用对离群值具有鲁棒性的归一化方法来进行处理数据。其原理就是在计算均值方差的时候,忽略掉数据中出现的离群值。它使用四分位间距而不是最大值和最小值,因此它对异常值具有鲁棒性。其计算公式如下:
v’ = \frac {v - Q_2}{ IQR}, IQR = Q_3 - Q_1 其中IQR称为四分位距,Q_2是中位数又称中位数,等于该样本中所有数值由小到大排列后第50%的数字,Q_1又称较小四分位数,等于该样本中所有数值由小到大排列后第25%的数字。Q_3又称较大四分位数,等于该样本中所有数值由小到大排列后第75%的数字。举个例子说明Q_1,Q_2,Q_3的计算,如下:
待计算数据为:

排序后为:
得到:

sklearn库中提供了RobustScaler函数来实现这一算法。例子如下:

from sklearn.preprocessing import RobustScaler

X = [[ 1., -2.,  2.],
     [ -2.,  5.,  3.],
     [ 4.,  6., -2.]]
transformer = RobustScaler().fit(X)

transformer.transform(X)
result

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容