「Python」sklearn第二弹-归一化和离散值编码

455 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天, 点击查看活动详情

本文主要讲解sklearn里面的归一化,其中包括-L1范式和L2范式。 还讲解了关于离散值编码,主要涉及到的编码方式有LabelEncoder和OneHotEncoder。


先介绍一下归一化:

归一化

why? --- 加快训练速度 归一化是缩放单个样本以具有单位范数的过程。

归一化实质是一种线性变换,线性变换有很多良好的性质,这些性质决定了对数据改变后不会造成“失效”,反而能提高数据的表现,这些性质是归一化的前提。

归一化能够加快模型训练速度统一特征量纲避免数值太大。值得注意的是,

归一化是对每一个样本做转换,所以是对数据的每一行进行变换。而之前我们讲过的方法是对数据的每一列做变换。

L1范式

调用L1范式:

from sklearn.preprocessing import normalize

x = normalize(x,'l1')

L1范式定义

向量x中每个元素的绝对值之和

公式表示:

x1=i=1nxi\begin{Vmatrix}x \end{Vmatrix}_1 = \sum_{i=1}^n |x_i|

L1范式归一化就是将样本中每个特征除以特征的L1范式。

通过normalize实现:

from sklearn.preprocessing import normalize
data = np.array([[-1,0,1],
                 [1,0,1],
                 [1,2,3]])
data = normalize(data,'l1')

>>>data
array([[-0.5  ,  0.   ,  0.5  ],
       [ 0.5  ,  0.   ,  0.5  ],
       [ 0.167,  0.333,  0.5  ]])

L2范式

x = normalize(x,'l2')

L2范式定义

向量元素的平方和再开平方根

公式:

x2=i=1nxi2\begin{Vmatrix}x \end{Vmatrix}_2 = \sqrt{\sum_{i=1}^n x_i^2}

L2范式归一化就是将样本中每个特征除以特征的L2范式

from sklearn.preprocessing import normalize
data = np.array([[-1,0,1],
                 [1,0,1],
                 [1,2,3]])
data = normalize(data,'l2')
>>>data
array([[-0.707,  0.   ,  0.707],
       [ 0.707,  0.   ,  0.707],
       [ 0.267,  0.535,  0.802]])

离散值编码

离散值特征变量可以分为有序类和无序类。

无序类:价值相等且可区分,各变量相互独立。如:性别(男/女)、颜色(红橙黄绿青蓝紫)

有序类:各变量有级别大小等逻辑关系。如:学历(高/中/低)、尺码(S/M/L/XL..)

为什么需要编码?

无序类:不能直接对特征进行赋值,比如male-1, female-0。

这是不科学的,因为这样一来就存在了大小关系,在算法学习时就会利用其大小关系来训练和预测。任何两个数值如1和0,都无法表示出male与female的价值相等且可区分的平行独立的关系.

但改成这样就可以了:male-[0,1],female-[1,0]

有序类

比如学历变量是博士、硕士、本科,分别用3-2-1来表示。

那么问题来了:为何可以用3-2-1来表示而不能用30-20-10来表示?如果1000-900-800呢?

但事实却是任何数字的排序都无法表达出变量的差异性。

何时不需要编码?

编码的作用本来就是让特征之间的距离计算更加合理,但是如果特征是离散的,并且不用one-hot编码就可以很合理的计算出距离,那么就没有必要进行one-hot编码。(如Titanic中的age特征)

有些基于树的算法在处理变量时,并不是基于向量空间度量,数值只是个类别符号,即没有偏序关系,所以不用进行独热编码。如:  Tree Model不太需要one-hot编码, 对于决策树来说,one-hot的本质是增加树的深度

编码的方式大致有三种:

  • LebelEncoder:适合处理字符型数据或者label类,一般先用此方法将字符型数据转化为数值型,然后再用get_dummies或OneHot编码。
  • get_dummies:pandas方法,多适用于DataFrame数据
  • OneHotEncoder:普遍的额编码方法

这里只简单的介绍一下第一种和第三种编码方式,请往下看:

LabelEncoder

在数据挖掘中,特征经常不是数值型的而是分类型的。

举个例子,一个人可能有["male", "female"],["from Europe", "from US", "from Asia"],["uses Firefox", "uses Chrome", "uses Safari", "uses Internet Explorer"]等分类的特征。

这些特征能够被有效地编码成整数,

比如["male", "from US", "uses Internet Explorer"]可以被表示为[0, 1, 3],["female", "from Asia", "uses Chrome"]表示为[1, 2, 1]。

在sklearn中,通过LabelEncoder来实现:

from sklearn.preprocessing import LabelEncoder
label = ['male','female']
int_label = LabelEncoder()
label = int_label.fit_transform(label)
>>>label
array([1, 0])

OneHotEncoder

上面那种整数特征表示并不能在sklearn的估计器中直接使用,因为这样的连续输入,估计器会认为类别之间是有序的,但实际却是无序的。

如将male,female,转换为1,0。1比0要大,机器就会把这个关系考虑进去,而male,female之间是没有这样的关系的。

所以我们需要使用另外一种编码方式,OneHot编码。 在sklearn中通过OneHotEncoder来实现,使用方法如下:

import numpy as np
from sklearn.preprocessing import OneHotEncoder
label = np.array([1,0])
label = np.array(label).reshape(len(label),1)
#先将X组织成(sample,feature)的格式
onehot_label = OneHotEncoder()
label = onehot_label.fit_transform(label).toarray()
>>>label
array([[0., 1.],
       [1., 0.]])

在回归,分类,聚类等机器学习算法中,特征之间距离的计算相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间.

对离散型特征进行one-hot编码是为了让距离的计算显得更加合理

编码后的特征扩维(如性别编码后变成male-[0,1],female-[1,0]),这样数据会变得稀疏

稀疏对算法来说是有好处的:

1.当某的元素时就意味着可以去除这个特征,则学习的难度、计算和存储开销都会降低

2.即便每个样本中有很多零元素,但是都不不是以整列或整行存在的,这样依旧有好处。 比如支持向量机之所以能在文本数据上有很好的性能,就是由于数据有高度的稀疏性,使得大多数问题可以变得线性可分,而且稀疏矩阵有高效的存储方法,节约存储空间。

参考链接: blog.csdn.net/qq_43243022…

往期好文推荐🪶

「MongoDB」Win10版安装教程

「Python」数字推盘游戏

「Python」sklearn第一弹-标准化和非线性转化

「Python」turtle绘制图形🎈