机器学习的多种编码方式,独热、标签等

一. 常见的特征类型

我们在学习机器学习的时候,往往会遇到各色各样的数据集。在拿到数据集那一刻,我们应该仔细看看数据集的内部情况。每一个样本通常带有多个特征的,一般特征类型分为连续型特征和离散型特征,离散型特征又分为类别特征和数值特征,性别(男,女)就是典型的类别特征。
编码往往应对的就是类别特征,无论是连续型特征,还是离散数值型特征,都可以通过简单的归一化就送进机器学习模型当中去。然而对于类别特征,仅有少数的模型支持字符串形式的类别特征的处理,例如决策树。因此,我们需要针对不同的场合,采用合适的编码方式对类别特征进行数值化。

二、编码方式

我们在学习sklearn和参加kaggle竞赛的时候,常常遇见各种类型的数据,需要采取适合的方式去编码,接下来就讲解目前主要的编码方式。

2.1 独热编码

什么是独热编码?为什么使用独热编码?在什么时候使用?我们需要带着这些疑问进行学习。
One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。也就是说该离散型类别特征有N个不同的取值,就有N个状态,就用N位寄存器(N位二进制)来表示N个不同的值。每N个比特位表示的值只有一个是1,其余为0,其实就是以二进制的形式表示,主要用于特征内部取值是无序的,例如颜色(红,蓝,绿。
独热编码在机器学习中的应用实例如下:

from sklearn import preprocessing.OneHotEncoder 
dem = OneHotEncoder()  
dem.fit([[0,0,3],
         [1,1,0],
         [0,2,1],
         [1,0,2]])  #这里一共有4个样本,3种特征
 
array = dem.transform([[0,1,3]]).toarray()  #这里使用一个新的数据来测试 
print(array)   # [[ 1  0  0  1  0  0  0  0  1]]

从中我们可以看出,对于第一个特征(0,1,0,1),有2种不同取值,故用2位比特位表示取值,0用10,1用01表示。对于第二个特征(0,1,2,0),有3种不同取值,故用3位比特位表示取值,0用100,1用010,2用001表示。
在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。
而我们使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征使用one-hot编码,确实会让特征之间的距离计算更加合理。
比如,有一个离散型特征,代表工作类型,该离散型特征,共有三个取值,不使用one-hot编码,其表示分别是x_1 = (1), x_2 = (2), x_3 = (3)。两个工作之间的距离是,(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2。那么x_1和x_3工作之间就越不相似吗?显然这样的表示,计算出来的特征的距离是不合理。那如果使用one-hot编码,则得到x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1),那么两个工作之间的距离就都是sqrt(2).即每两个工作之间的距离是一样的,显得更合理。

2.2 标签编码

传统硬编码,即直接对类别特征进行了大量映射,有多少类别取值就代表了多少。这种硬编码方式简单粗暴,方便快捷。但其仅在类别特征内部取值是有序的情况才好使用。假设特征取值有n个不同值,即n个类别,那么将按照特征数据的大小将其编码成0-(n-1)之间的整数。
标签编码在机器学习中的应用如下:

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(['undergraduate', 'master', 'PhD', 'Postdoc']) #相当于训练标签编码器,得到每一个类别值所对应的编码
le.transform(['undergraduate', 'master', 'PhD', 'Postdoc'])#将上面得到的标签编码器对输入数据进行编码

经过上述程序的运行,字符串被编码0-3的整数, ‘master’——>0,‘PhD’——>1,
‘Postdoc’——>2,‘undergraduate’——>3(按Ascil码从小到大进行编排)。相信到这里,大家就知道标签编码的运行规则。

2.3 序号编码

序号编码是处理一个数据集都是类别特征的编码方法,并且其类别特征内部取值是具有大小顺序的情况,因此该方法用的较少。
信号编码在机器学习中的应用如下:

import pandas as pd
from sklearn.preprocessing import OrdinalEncoder

categorical_df = pd.DataFrame({'stuent_id': ['101', '102', '103', '104'],
                               'name': ['Li', 'Huang', 'Ann', 'John'], 
                               'ranking': ['third', 'second', 'first', 'second']})
print(categorical_df)
print('--'*20)

encoder = OrdinalEncoder() #创建OrdinalEncoder对象

encoder.fit(categorical_df) #将数据categorical_df载入encoder中
categorical_df = encoder.transform(categorical_df) #将载入的数据进行OrdinalEncoder

print(categorical_df)

在这里插入图片描述

从输出我们可以看到所有的特征内部取值被编码,这与标签编码类似。但要注意的是标签编码只对某个特征内部取值进行编码。

2.4 频数编码

频数编码就是将类别特征内部取值用该取值出现的频数替换,这就是所谓的频数编码,不过这种编码方式用得不多。
比如某个分类中’Peking’出现了10次,那么’Peking’就会被替换为10. 我们可以用
categorical-encodings包中的CountEncoder实现。

参考资料:[机器学习中常见的编码形式]

  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值