机器学习基础与实践(二)——数据转换

本文目录:

一.标准化的原因 二.适用情况 三.三种数据变换方法的含义与应用 四.具体方法及代码 一)标准化 1.1 scale----零均值单位方差1.2 StandardScaler 二)归一化 2.1 MinMaxScaler(最小最大值标准化)2.2 MaxAbsScaler(绝对值最大标准化) 2.3 对稀疏数据进行标准化 2.4 对离群点进行标准化 三)正则化 3.1 L1、L2正则化 四)二值化 4.1特征二值化 五)对类别特征进行编码 六)缺失值的插补 七)生成多项式特征 八)自定义转换

一.标准化的原因

通常情况下是为了消除量纲的影响。譬如一个百分制的变量与一个5分值的变量在一起怎么比较?只有通过数据标准化,都把它们标准到同一个标准时才具有可比性,一般标准化采用的是Z标准化,即均值为0,方差为1,当然也有其他标准化,比如0--1标准化等等,可根据自己的数据分布情况和模型来选择

二.适用情况

看模型是否具有伸缩不变性。

不是所有的模型都一定需要标准化,有些模型对量纲不同的数据比较敏感,譬如SVM等。当各个维度进行不均匀伸缩后,最优解与原来不等价,这样的模型,除非原始数据的分布范围本来就不叫接近,否则必须进行标准化,以免模型参数被分布范围较大或较小的数据主导。但是如果模型在各个维度进行不均匀伸缩后,最优解与原来等价,例如logistic regression等,对于这样的模型,是否标准化理论上不会改变最优解。但是,由于实际求解往往使用迭代算法,如果目标函数的形状太“扁”,迭代算法可能收敛得很慢甚至不收敛。所以对于具有伸缩不变性的模型,最好也进行数据标准化。

三.三种数据变换方法的含义与应用

Rescaling(重缩放/归一化):通常是指增加或者减少一个常数,然后乘以/除以一个常数,来改变数据的衡量单位。例如:将温度的衡量单位从摄氏度转化为华氏温度。

Normalizing(正则化):通常是指除以向量的范数。例如:将一个向量的欧氏长度等价于1 。在神经网络中,“正则化”通常是指将向量的范围重缩放至最小化或者一定范围,使所有的元素都在[0,1]范围内。通常用于文本分类或者文本聚类中。

Standardizing(标准化):通常是为了消除不同属性或样方间的不齐性,使同一样方内的不同属性间或同一属性在不同样方内的方差减小。例如:如果一个向量包含高斯分布的随机值,你可能会通过除以标准偏差来减少均值,然后获得零均值单位方差的“标准正态”随机变量。

那么问题是,当我们在训练模型的时候,一定要对数据进行变换吗?这得视情况而定。很多人对多层感知机有个误解,认为输入的数据必须在[0,1]这个范围内。虽然标准化后在训练模型效果会更好,但实际上并没有这个要求。但是最好使输入数据中心集中在0周围,所以把数据缩放到[0,1]其实并不是一个好的选择。

如果你的输出激活函数的范围是[0,1](sigmoid函数的值域),那你必须保证你的目标值也在这个范围内。但通常请款下,我们会使输出激活函数的范围适应目标函数的分布,而不是让你的数据来适应激活函数的范围。

当我们使用激活函数的范围为[0,1]时,有些人可能更喜欢把目标函数缩放到[0.1,0.9]这个范围。我怀疑这种小技巧的之所以流行起来是因为反向传播的标准化太慢了导致的。但用这种方法可能会使输出的后验概率值不对。如果你使用一个有效的训练算法的话,完全不需要用这种小技巧,也没有必要去避免溢出(overflow)

四.具体方法及代码

一)标准化

1.1 scale----零均值单位方差

1.2 StandardScaler----计算训练集的平均值和标准差,以便测试数据集使用相同的变换

注:

1)若设置with_mean=False 或者 with_std=False,则不做centering 或者scaling处理。

2)scale和StandardScaler可以用于回归模型中的目标值处理。

二)归一化----将数据特征缩放至某一范围(scalingfeatures to a range)

另外一种标准化方法是将数据缩放至给定的最小值与最大值之间,通常是0与1之间,可用MinMaxScaler实现。或者将最大的绝对值缩放至单位大小,可用MaxAbsScaler实现。

使用这种标准化方法的原因是,有时数据集的标准差非常非常小,有时数据中有很多很多零(稀疏数据)需要保存住0元素。

2.1 MinMaxScaler(最小最大值标准化)

公式:X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0)) ;

X_scaler = X_std/ (max - min) + min

2.2 MaxAbsScaler(绝对值最大标准化)

与上述标准化方法相似,但是它通过除以最大值将训练集缩放至[-1,1]。这意味着数据已经以0为中心或者是含有非常非常多0的稀疏数据。

其实在scale模块里,也提供了这两种方法: minmax_scale和maxabs_scale

2.3 对稀疏数据进行标准化

对稀疏数据进行中心化会破坏稀疏数据的结构,这样做没什么意义。但是我们可以对稀疏数据的输入进行标准化,尤其是特征在不同的标准时。MaxAbsScaler 和 maxabs_scale是专门为稀疏数据设计的,也是常用的方法。但是scale 和 StandardScaler只接受scipy.sparse的矩阵作为输入,并且必须设置with_centering=False。否则会出现 ValueError且破坏稀疏性,而且还会无意中分配更多的内存导致内存崩溃。RobustScaler不适用于稀疏数据的输入,但是你可以用 transform 方法。

scalers接受压缩的稀疏行(Compressed Sparse Rows)和压缩的稀疏列(Compressed Sparse Columns)的格式(具体参考scipy.sparse.csr_matrix 和scipy.sparse.csc_matrix)。其他的稀疏格式会被转化成压缩的稀疏行(Compressed Sparse Rows)格式。为了避免这种不必要的内存拷贝,推荐使用CSR或者CSC的格式。如果数据很小,可以在稀疏矩阵上运用toarray 方法。

2.4 对离群点进行标准化

如果你的数据有离群点(上一篇我们提到过),对数据进行均差和方差的标准化效果并不好。这种情况你可以使用robust_scale 和 RobustScaler 作为替代。它们有对数据中心化和数据的缩放鲁棒性更强的参数。

三)正则化

3.1 L1、L2正则化

注:稀疏数据输入:

normalize 和 Normalizer 既接受稠密数据(dense array-like),也接受稀疏矩阵(from scipy.sparse)作为输入

稀疏数据需要转换成压缩的稀疏行(Compressed Sparse Rows)格式(详见scipy.sparse.csr_matrix),为了避免不必要的内存拷贝,推荐使用CSR。

四)二值化

4.1特征二值化

特征二值化是把数值特征转化成布尔值的过程。这个方法对符合多变量伯努利分布的输入数据进行预测概率参数很有效。详细可以见这个例子sklearn.neural_network.BernoulliRBM.

此外,在文本处理中也经常会遇到二值特征值(很可能是为了简化概率推理),即使在实际中正则化后的词频或者TF-IDF的值通常只比未正则化的效果好一点点。

对于 Normalizer,Binarizer工具类通常是在Pipeline阶段(sklearn.pipeline.Pipeline)的前期过程会用到。下面举一个具体的例子:

注:稀疏数据输入:

binarize 和 Binarizer 既接受稠密数据(dense array-like),也接受稀疏矩阵(from scipy.sparse)作为输入

稀疏数据需要转换成压缩的稀疏行(Compressed Sparse Rows)格式(详见scipy.sparse.csr_matrix),为了避免不必要的内存拷贝,推荐使用CSR。

五)对类别特征进行编码

我们经常会遇到一些类别特征,这些特征不是离散型的数值,而是这样的:["男性","女性"],["来自欧洲","来自美国","来自亚洲"],["使用Firefox浏览器","使用Chrome浏览器","使用Safari浏览器","使用IE浏览器"]等等。这种类型的特征可以被编码为整型(int),如["男性","来自美国","使用IE浏览器"]可以表示成[0,1,3],["女性","来自亚洲","使用Chrome浏览器"]可以表示成[1,2,1]。这些整数式的表示不能直接作为sklearn的参数,因为我们需要的是连续型的输入,而且我们通常是有序的翻译这些特征,而不是所有的特征都是有序化的(譬如浏览器就是按人工排的序列)。

将这些类别特征转化成sklearn参数中可以使用的方法是:使用one-of-K或者one-hot编码(独热编码OneHotEncoder)。它可以把每一个有m种类别的特征转化成m中二值特征。举例如下:

默认情况下,特征的类别数量是从数据集里自动判断出来的。当然,你也可以用n_values这个参数。我们刚刚举的例子中有两种性别,三种地名和四种浏览器,当我们fit之后就可以将我们的数据转化为数值了。从结果中来看,第一个数字代表性别([0,1]代表男性,女性),第二个数字代表地名([0,1,2]代表欧洲、美国、亚洲),最后一个数字代表浏览器([3,0,1,2]代表四种浏览器)

此外,字典格式也可以编码: Loading features from dicts

OneHotEncoder参数:class sklearn.preprocessing.OneHotEncoder(n_values='auto', categorical_features='all', dtype=<class 'float'>, sparse=True, handle_unknown='error')

n_values : ‘auto’, int or array of ints

每个特征的数量

  • ‘auto’ : 从训练数据的范围中得到
  • int : 所有特征的最大值(number)
  • array : 每个特征的最大值(number)

categorical_features: “all” or array of indices or mask :

确定哪些特征是类别特征

  • ‘all’ (默认): 所有特征都是类别特征,意味着所有特征都要进行OneHot编码
  • array of indices: 类别特征的数组索引
  • mask: n_features 长度的数组,切dtype = bool

非类别型特征通常会放到矩阵的右边

dtype : number type, default=np.float

输出数据的类型

sparse : boolean, default=True

设置True会返回稀疏矩阵,否则返回数组

handle_unknown : str, ‘error’ or ‘ignore’

当一个不明类别特征出现在变换中时,报错还是忽略

六)缺失值的插补

上篇我们讲了五种方法来解决缺失值的问题,其实sklearn里也有一个工具Imputer可以对缺失值进行插补。Imputer类可以对缺失值进行均值插补、中位数插补或者某行/列出现的频率最高的值进行插补,也可以对不同的缺失值进行编码。并且支持稀疏矩阵。

在稀疏矩阵中,缺失值被编码为0存储为矩阵中,这种格式是适合于缺失值比非缺失值多得多的情况。此外,Imputer类也可以用于Pipeline中

Imputor类的参数:class sklearn.preprocessing.Imputer(missing_values='NaN', strategy='mean', axis=0, verbose=0, copy=True)

missing_values : int或"NaN",默认NaN(String类型)

strategy : string, 默认为mean,可选则mean、median、most_frequent

axis :int, 默认为0(axis = 0,对列进行插值;axis= 1,对行进行插值)

verbose : int, 默认为0

copy : boolean, 默认为True

True:会创建一个X的副本

False:在任何合适的地方都会进行插值。

但是以下四种情况,计算设置的copy = Fasle,也会创建一个副本:

1.X不是浮点型数组2.X是稀疏矩阵,而且miss_value = 0

3.axis= 0,X被编码为CSR矩阵

4.axis= 1,X被编码为CSC矩阵

举个实例(在用随机森林算法之前先用Imputer类进行处理):

结果:

七)生成多项式特征

在输入数据中增加非线性特征可以有效的提高模型的复杂度。简单且常用的方法就是使用多项式特征(polynomial features),可以得到特征的高阶交叉项:

这样,

就被转化成

然而有时候我们只需要特征的交叉项,可以设置interaction_only=True来得到:

这样

就转化成了

这个方法可能大家在工作中比较少见,但世界上它经常用于核方法中,如选择多项式核时 ( sklearn.svm.SVC, sklearn.decomposition.KernelPCA)

八)自定义转换

如果以上的方法觉得都不够,譬如你想用对数据取对数,可以自己用 FunctionTransformer自定义一个转化器,并且可以在Pipeline中使用

告诉你怎么用:

如果你在做一个分类任务时,发现第一主成分与这个不相关,你可以用FunctionTransformer把第一列除去,剩下的列用PCA:

结果:

写到这里基本上关于数据转化的方法已经介绍的差不多了,周四写第三篇--数据降维。写的比较仓促,有错误的欢迎提出来~

Charlotte ,数学系的数据挖掘民工,喜欢算法和建模。

欢迎关注我的博客:

http://www.cnblogs.com/charlotte77/

原文发布于微信公众号 - CDA数据分析师(cdacdacda)

原文发表时间:2016-07-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从流域到海域

How to Use the TimeDistributed Layer for Long Short-Term Memory Networks in Python 译文

How to Use the TimeDistributed Layer for Long Short-Term Memory Networks in Pyth...

567120
来自专栏数据结构与算法

圆的反演变换

挺神奇的东西,网上没有多少资料,我也不是太懂,代码什么的都没写过,那就抄一下百度百科吧

15920
来自专栏数据派THU

fastText、TextCNN、TextRNN…这套NLP文本分类深度学习方法库供你选择

文经公众号「机器人圈」授权转载(微信号:ROBO_AI) 本文长度为4473字,建议阅读10分钟 本文为你介绍一套NLP文本分类深度学习方法库及其12个模型。 ...

3.2K120
来自专栏人工智能LeadAI

ResNet原理及其在TF-Slim中的实现

01 摘要 微软的深度残差网络ResNet源于2016年CVPR最佳论文---图像识别中的深度残差学习(Deep Residual Learning for I...

54870
来自专栏本立2道生

滤波器——BoxBlur均值滤波及其快速实现

在数字图像处理的语境里,图像一般是二维或三维的矩阵,卷积核(kernel)和滤波器(filter)通常指代同一事物,即对图像进行卷积或相关操作时使用的小矩阵,尺...

16110
来自专栏MixLab科技+设计实验室

用谷歌新开源的deeplearnJS预测互补颜色

本文翻译自deeplearnJS的示例教程,并结合了我在学习过程中的理解。 deeplearnJS简介: deeplearn.js是用于机器学习的开源WebGL...

33380
来自专栏量化投资与机器学习

【ML系列】手把手教你用Numpy构建神经网络!(附代码)

比如使用Keras,TensorFlow或PyTorch这样的高级框架,我们可以快速构建非常复杂的模型。但是,需要花时间去了解其内部结构并理解基本原理。今天,将...

33610
来自专栏智能算法

决策树算法之----C4.5

1. C4.5算法简介 C4.5是一系列用在机器学习和数据挖掘的分类问题中的算法。它的目标是监督学习:给定一个数据集,其中的每一个元组都能用一组属性...

476120
来自专栏梦里茶室

TensorFlow 深度学习笔记 TensorFlow实现与优化深度神经网络

全连接神经网络 辅助阅读:TensorFlow中文社区教程 - 英文官方教程 代码见:full_connect.py Linear Model 加载lesso...

214100
来自专栏进击的程序猿

如何构建一个简单的神经网络如何构建一个简单的神经网络

最近报名了Udacity的深度学习基石,这是介绍了第二部分神经网络入门,第一篇是线性回归背后的数学. 本文notebook的地址是:https://githu...

14430

扫码关注云+社区

领取腾讯云代金券