• 【机器学习技巧】之特征工程:数字编码以及One-hot独热编码的几种方式(sklearn与pandas处理方式)


    本文主要对OneHot独热编码进行了简单介绍,同时介绍了在sklearn与pandas中进行数字编码以及One-hot独热编码的几种方式。

    1. OneHot独热编码介绍

    1.1 为什么要用One-hot编码

    在建模过程中,我们通常会碰到各种类型的属性,如果是标称型属性(非数值类型的属性),也就是不具备序列性、不能比较大小的属性,通常我们不能用简单的数值来粗暴替换。因为属性的数值大小会影响到权重矩阵的计算,不存在大小关系的属性,其权重也不应该发生相应的变化,那么我们就需要用到One-hot编码(也有人称独热编码)这种特殊的编码方式了。

    1.2 One-hot举例

    data = pd.DataFrame([
                [ 'M', 10.1], 
                [ 'L', 13.5], 
                [ 'XL', 15.3],
                [ 'XL', 16.3]])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    One-hot编码后变为:

    data = array([[0, 1, 0, 10.1],
    [1, 0, 0, 13.5],
    [0, 0, 1, 15.3],
    [0, 0, 1, 16.3]])

    1.3 One-hot使用范围

    one-hot通常用在GBDT、XGBoost这些模型里面都挺好的,但是用在逻辑回归里不行。因为逻辑回归要求变量间相互独立,如果你只有一个属性需要做one-hot编码还好,如果你有多个属性需要做one-ont编码,那么当某个样本的多个one-hot属性同时为1时,这两个属性就完全相关了,必然会导致singular error,也就是非奇异矩阵不能求解唯一解,得不出唯一的模型,但是你又不可能把同一个属性的某一个one-hot延伸变量删除。

    如果在逻辑回归中入模标称属性,可以直接替换成数值,然后做woe变换,用每个类别的woe值来代替原来的数值,这样既能够避免生成相关性强的变量,又能避开类别间大小无法比较的问题。

    创建基础数据

    import pandas as pd
    import numpy as np
    
    • 1
    • 2
    data = pd.DataFrame([
                ['yellow', 'M', 10.1, 'class1'], 
                ['red', 'L', 13.5, 'class2'], 
                ['blue', 'XL', 15.3, 'class1'],
                ['green', 'XL', 16.3, 'class3']])
     
    data.columns = ['颜色', '大小', '价格', '类别标签']
    data
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    颜色大小价格类别标签
    0yellowM10.1class1
    1redL13.5class2
    2blueXL15.3class1
    3greenXL16.3class3

    2. sklearn机器学习中Onehot编码方式

    2.1 将分类特征进行数字编码—LabelEncoder将分类特征数字化

    from sklearn.preprocessing import LabelEncoder
    encoder = LabelEncoder()
    category = encoder.fit_transform(data['颜色'])
    print("颜色编码:",category)
    print("编码对应的颜色:",encoder.classes_)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    颜色编码: [3 2 0 1]
    编码对应的颜色: ['blue' 'green' 'red' 'yellow']
    
    • 1
    • 2

    但是LabelEncoder一次只能处理一个属性,因此需要使用循环分别对属性进行处理

    columns = ['颜色','大小','类别标签']
    data2 = data.copy()
    for column in columns:
        data2[column] = encoder.fit_transform(data[column])
        print("{}编码顺序:{}".format(column, encoder.classes_))
    data2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    颜色编码顺序:['blue' 'green' 'red' 'yellow']
    大小编码顺序:['L' 'M' 'XL']
    类别标签编码顺序:['class1' 'class2' 'class3']
    
    • 1
    • 2
    • 3
    颜色大小价格类别标签
    03110.10
    12013.51
    20215.30
    31216.32

    2.2 Onehot编码方法一:LabelEncoder后使用OneHotEncoder

    from sklearn.preprocessing import OneHotEncoder
    columns = ['颜色','大小','类别标签']
    enc = OneHotEncoder()
    # 将['颜色','大小','类别标签']这3列进行独热编码
    enc.fit_transform(data2[columns]).toarray()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    array([[0., 0., 0., 1., 0., 1., 0., 1., 0., 0.],
           [0., 0., 1., 0., 1., 0., 0., 0., 1., 0.],
           [1., 0., 0., 0., 0., 0., 1., 1., 0., 0.],
           [0., 1., 0., 0., 0., 0., 1., 0., 0., 1.]])
    
    • 1
    • 2
    • 3
    • 4

    2.3 Onehot编码方法二:直接对文本使用LabelBinarizer

    LabelBinarizer 每次也只能对一个特征进行独热编码,需要使用循环对每个特征进行编码

    from sklearn.preprocessing import LabelBinarizer
    enc = LabelBinarizer()
    transform_data = enc.fit_transform(data['颜色'])
    transform_data
    
    • 1
    • 2
    • 3
    • 4
    array([[0, 0, 0, 1],
           [0, 0, 1, 0],
           [1, 0, 0, 0],
           [0, 1, 0, 0]])
    
    • 1
    • 2
    • 3
    • 4
    transform_data = enc.fit_transform(data['大小'])
    transform_data
    
    • 1
    • 2
    array([[0, 1, 0],
           [1, 0, 0],
           [0, 0, 1],
           [0, 0, 1]])
    
    • 1
    • 2
    • 3
    • 4

    2.4 Onehot编码方法三:DictVectorizer

    from sklearn.feature_extraction import DictVectorizer
    dict = DictVectorizer(sparse=False)
    dict_data= dict.fit_transform(data.to_dict(orient="records"))
    dict_data
    
    • 1
    • 2
    • 3
    • 4
    array([[10.1,  0. ,  1. ,  0. ,  1. ,  0. ,  0. ,  0. ,  0. ,  0. ,  1. ],
           [13.5,  1. ,  0. ,  0. ,  0. ,  1. ,  0. ,  0. ,  0. ,  1. ,  0. ],
           [15.3,  0. ,  0. ,  1. ,  1. ,  0. ,  0. ,  1. ,  0. ,  0. ,  0. ],
           [16.3,  0. ,  0. ,  1. ,  0. ,  0. ,  1. ,  0. ,  1. ,  0. ,  0. ]])
    
    • 1
    • 2
    • 3
    • 4
    # 查看各列标签名称
    dict.get_feature_names()
    
    • 1
    • 2
    ['价格',
     '大小=L',
     '大小=M',
     '大小=XL',
     '类别标签=class1',
     '类别标签=class2',
     '类别标签=class3',
     '颜色=blue',
     '颜色=green',
     '颜色=red',
     '颜色=yellow']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3. Pandas中Onehot编码方式

    3.1 Pandas将分类特征进行数字编码方式–pd.factorize()

    data_category, data_class = pd.factorize(data['大小'])
    print(data_category)
    print(data_class)
    
    • 1
    • 2
    • 3
    [0 1 2 2]
    Index(['M', 'L', 'XL'], dtype='object')
    
    • 1
    • 2

    3.2 Onehot编码–pd.get_dummies()

    data_oneHot = pd.get_dummies(data)
    
    • 1
    data_oneHot
    
    • 1
    价格颜色_blue颜色_green颜色_red颜色_yellow大小_L大小_M大小_XL类别标签_class1类别标签_class2类别标签_class3
    010.10001010100
    113.50010100010
    215.31000001100
    316.30100001001

    4. 总结

    综合上述方法:
    个人认为下面两种方式转化为One_hot类型特征最方便:

    1. sklearn中使用DictVectorizer
    2. Pandas中使用pd.get_dummies
  • 相关阅读:
    Linux下的stratis高级存储
    数理天地杂志数理天地杂志社数理天地编辑部2022年第20期目录
    Redis与分布式-分布式锁
    SpringCloud学习笔记(二)Eureka 服务注册与发现
    【aloam】ubuntu20.04 配置 aloam 环境,编译过程报错及成功解决方法
    华云桌面云:满足多种用户场景 畅享数字化办公新体验
    CS鱼饵制作
    【云原生】Prometheus+Grafana on K8s 环境部署
    基于单片机的多关节机械臂抓取系统
    CentOS安装Docker
  • 原文地址:https://blog.csdn.net/qq_42589613/article/details/127899266