我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

在本文中,苏南大叔准备讲解一下sklearn比较常用的独热编码器,英文名是OneHotEncoder。独热编码主要用于分类特征的各个取值之间是无序的情况,各种特征之间理论上并没有顺序或者大小的关系。但是为了机器学习,可能还是需要把这些特征的取值进行数字化。

苏南大叔:机器学习,如何理解sklearn的独热编码器OneHotEncoder? - 独热编码器
机器学习,如何理解sklearn的独热编码器OneHotEncoder?(图1-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程学习故事。本文测试环境:win10python@3.12.0scikit-learn@1.3.2

独热编码器

下面的内容是网络上关于One-Hot编码的解释:

One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。
One-Hot编码是分类变量作为二进制向量的表示。这首先要求将分类值映射到整数值。然后,每个整数值被表示为二进制向量,除了整数的索引之外,它都是零值,它被标记为1。

苏南大叔的理解上:

  • 不同的特征值越多,所需要的值长度越多。有多少特征值,就会有多长的编码结果。
  • 某个特征的最终编码结果里面,位数为count(所有特征值),其中只有一个为1,其余都是0
  • 所有特征值按顺序排序后,其编码结果也是有规律的。1【从左到右】依次转移。
  • 随着特征值的不断增多,编码结果也会不断变化,其结果也会大量增加。所以...

测试代码

from sklearn import preprocessing  
one = preprocessing.OneHotEncoder()
X = [
    ["老许", 3, "cat"],
    ["虎子", 5, "dog"],
    # ["二赖子", 3, "dog"],
    # ["老白", 8, "cat"],
    # ["小黑", 10, "dog"],
]
one.fit(X)
print(one.transform([["虎子",5,"dog"]]).toarray())
# [[0. 1. 0. 1. 0. 1.]]
print(one.transform([["老许",5,"dog"]]).toarray())  
# [[1. 0. 0. 1. 0. 1.]]
print(one.inverse_transform([[1,0,0,1,0,1]]))    # [['老许' 5 'dog']]

字典功能属性 .categories_

虽然没有.classes_属性,但是存在一个类似的.categories_属性。

# print(one.classes_)                            # 'OneHotEncoder' object has no attribute 'classes_'
print(one.categories_)

输出:

[
array(['老许', '虎子'], dtype=object), 
array([3, 5], dtype=object), 
array(['cat', 'dog'], dtype=object)
]

输出项 toarray()

这种OneHotEncoder的编码结果实际是:

a = one.transform([["虎子",5,"dog"]])
print(a,type(a))

输出:

  (0, 1)        1.0
  (0, 3)        1.0
  (0, 5)        1.0 <class 'scipy.sparse._csr.csr_matrix'>

但是通过.toarray()才能看到以前其它编码器的类似结果。

b =  one.transform([["虎子",5,"dog"]]).toarray()
print(b,type(b))

输出:

[[0. 1. 0. 1. 0. 1.]] <class 'numpy.ndarray'>

这个scipy.sparse._csr.csr_matrix类型,留到后续文章说明。

编码顺序

这里的编码顺序,很显然还是按照unicode编码的数字来排序的。

第几列特征特征值unicode数字独特编码
第一列[老]许3276910
第一列[虎]子3438201
第二列35110
第二列55301
第三列[c]at9910
第三列[d]og10001

输入项

输入只接受二维数组,不接受一维向量。可以接受二维list/二维ndarray/dataframe。但是,输入是二维ndarray或者dataframe的话,可能会面临变量类型转换的问题。例如:

from sklearn import preprocessing  
one = preprocessing.OneHotEncoder()
X = [
    ["老许", 3, "cat"],
    ["虎子", 5, "dog"],
]

##########################
# 注意这里有转化
##########################

one.fit(X)
print(one.transform([["虎子",5,"dog"]]).toarray())

转化为ndarray

import numpy as np
X = np.array(X)

转化为dataframe:

import pandas as pd
X = pd.DataFrame(X)

都会报错:

ValueError: Found unknown categories ['5'] in column 1 during transform

实际上就是数字5被强制转化为字符串5,所导致的问题。但是,这并不是说dataframe或者ndarray不能转化为独热。而是可能会有一些类型上的变化,可能会做一些简单的变化。

其它结论

  • 输入只接受二维数组,不接受一维向量。可以接受二维list/二维ndarray/dataframe
  • 既然输入项是二维的,则一样不存在.classes_了。会报错:
  • 这个OneHotEncoder的编码结果可以翻转,倒是很意外的事情。毕竟0和1的组合还是很多的。

后续内容

如果某一列定义了CategoricalDtype,那么独热码结果还是会有较大的变化。这种情况待后续补充。

相关文章

结语

苏南大叔的更多sklearn的机器学习文章,请参考苏南大叔的文章:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python    sklearn