机器学习,如何理解sklearn的独热编码器OneHotEncoder?
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
在本文中,苏南大叔准备讲解一下sklearn
比较常用的独热编码器,英文名是OneHotEncoder
。独热编码主要用于分类特征的各个取值之间是无序的情况,各种特征之间理论上并没有顺序或者大小的关系。但是为了机器学习,可能还是需要把这些特征的取值进行数字化。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程学习故事。本文测试环境:win10
,python@3.12.0
,scikit-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数字 | 独特编码 |
---|---|---|---|
第一列 | [老]许 | 32769 | 10 |
第一列 | [虎]子 | 34382 | 01 |
第二列 | 3 | 51 | 10 |
第二列 | 5 | 53 | 01 |
第三列 | [c]at | 99 | 10 |
第三列 | [d]og | 100 | 01 |
输入项
输入只接受二维数组,不接受一维向量。可以接受二维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
的机器学习文章,请参考苏南大叔的文章:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。