• 【sklearn】数据预处理之独热编码(含两种实现方式+代码理解)


    最近学习机器学习,接触到独热编码相关内容,参考了一些资料,加上自己的思考,做出了如下总结:

    一、什么是独热编码

    独热编码,即One-Hot编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。

    说起来这么复杂,举个例子就很容易理解了:

    比如爱吃的水果有3种:苹果、葡萄和橙子,转换成独热编码分别表示为(此时上述描述中的N=3):001, 010, 100。(当然转换成100, 010, 001也可以,只要有确定的一一对应关系即可)。

    那么提出一个问题,苹果、葡萄和橙子分别转换成1, 2, 3行不行?

    一般不这样处理,这样处理也不叫独热编码了,只能说是文本转换成数字,具体原因可以往下看。

    二、为什么要进行独热编码

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

    使用独热编码(One-Hot Encoding),将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征使用独热编码(One-Hot Encoding),会让特征之间的距离计算更加合理。

    接下来举例说明:

    我们选取离散型特征,共有五个取值,不使用独热编码(One-Hot Encoding),其表示分别是:

    演员 =0;厨师 =1;公务员 =2;工程师 =3;律师 =4

    两个工作之间的距离是:

    d(演员,厨师) = 1
    d(厨师,公务员) = 1
    d(公务员,工程师) = 1
    d(工程师,律师) = 1
    d(演员,公务员) = 2
    d(演员,工程师) = 3

    显然这样的表示,计算出来的特征的距离是不合理。那如果使用独热编码(One-Hot Encoding),则得到d(演员,厨师) = 1与d(演员,公务员)都是1。那么,两个工作之间的距离就都是sqrt(2)。即每两个工作之间的距离是一样的,显得更合理。

    此处参考文章为:

    https://www.jianshu.com/p/42e93acacc52
    
    • 1

    三、如何用Python实现独热编码

    方法1:get_dummies

    将类别变量转换成虚拟变量/指示变量,也叫哑变量。

    我们看一下它的定义:

    pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, 
                       sparse=False, drop_first=False, dtype=None)
    
    • 1
    • 2

    各参数的含义:

    data: array-like, Series, or DataFrame

    prefix: string, list of strings, or dict of strings, default None

    prefix_sep: str, default ‘_’ (转换后列名的前缀)

    dummy_na: bool, default False(增加一列表示空缺值,如果False就忽略空缺值)

    columns: list-like, default None (指定需要实现类别转换的列名)

    sparse: bool, default False

    drop_first: bool, default False (获得k中的k-1个类别值,去除第一个)

    dtype: dtype, default np.uint8

    举例说明一下:

    import numpy as np
    import pandas as pd
    s=pd.Series(list('abcd'))
    s_=pd.get_dummies(s)
    print(s_)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们看一下结果:

       a  b  c  d
    0  1  0  0  0
    1  0  1  0  0
    2  0  0  1  0
    3  0  0  0  1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们换一种表示方法:

    import numpy as np
    import pandas as pd
    s=pd.Series(list('abcd'))
    s_=pd.get_dummies(s,drop_first=True)
    print(s_)
    
    • 1
    • 2
    • 3
    • 4
    • 5
       b  c  d
    0  0  0  0
    1  1  0  0
    2  0  1  0
    3  0  0  1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    再来看一个例子:

    import numpy as np
    import pandas as pd
    df=pd.DataFrame({'city':['hang zhou','shang hai','bei jing'],'population':[20,32,51],'class':['A','A+','A+']})
    print(df)
    df_=pd.get_dummies(df)
    print(df_)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    首先看一下df的输出结果:

            city  population class
    0  hang zhou          20     A
    1  shang hai          32    A+
    2   bei jing          51    A+
    
    • 1
    • 2
    • 3
    • 4

    看一下df_的输出结果:

       population  city_bei jing  city_hang zhou  city_shang hai  class_A  class_A+
    0          20              0               1               0        1         0
    1          32              0               0               1        0         1
    2          51              1               0               0        0         1
    
    • 1
    • 2
    • 3
    • 4

    方法2:sklearn

    Sklearn提供了一个编码器OneHotEncoder,用于将整数分类值转换成独热向量。

    我们举一个例子:

    from scipy.io import loadmat
    from sklearn.preprocessing import OneHotEncoder
    
    dataset=loadmat('neural_network_dataset.mat')
    print('数据集展示为:\n',dataset)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    展示一下数据集的样子:

    数据集展示为:
     {'__header__': b'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Sun Oct 16 13:09:09 2011', '__version__': '1.0', '__globals__': [], 'X': array([[0., 0., 0., ..., 0., 0., 0.],
           [0., 0., 0., ..., 0., 0., 0.],
           [0., 0., 0., ..., 0., 0., 0.],
           ...,
           [0., 0., 0., ..., 0., 0., 0.],
           [0., 0., 0., ..., 0., 0., 0.],
           [0., 0., 0., ..., 0., 0., 0.]]), 'y': array([[10],
           [10],
           [10],
           ...,
           [ 9],
           [ 9],
           [ 9]], dtype=uint8)}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    接下来我们把标签向量转换为独热向量:

    X=dataset['X']
    y=dataset['y']
    encoder=OneHotEncoder(sparse=False)
    y_onehot=encoder.fit_transform(y)
    print(y[0])
    print(y_onehot[0,:])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    我们看一下输出结果:

    [10]
    [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
    
    • 1
    • 2
  • 相关阅读:
    拉格朗日插值法(理论详解)
    【洛谷 P3743】kotori的设备 题解(二分答案+递归)
    CNN的识别机制
    搜索算法工程师必备知识储备
    winform开发小技巧
    web前端期末大作业——基于HTML+CSS+JavaScript蓝色的远程监控设备系统后台管理界面模板
    算法进阶-2sat-cf-1657F
    CP AUTOSAR标准之COM(AUTOSAR_CP_SWS_COM)(更新中……)
    Redis学习笔记17:基于spring data redis及lua脚本批处理scan指令查询永久有效的key
    一个宁静祥和没有bug的下午和SqlSession的故事
  • 原文地址:https://blog.csdn.net/wzk4869/article/details/126852040