one-hot编码

one-hot
机器学习算法无法直接用于数据分类。数据分类必须转换为数字才能进一步进行。

在本教程中,你将发现如何将输入或输出的序列数据转换为一种热编码,以便于你在Python中深度学习的序列分类问题中使用。

看完本教程后,你将会了解:

· 1.什么是整数编码和One-Hot编码,以及为什么它们在机器学习中是必需的。

· 2.如何在Python中手工计算一个整数编码和One-Hot编码。

· 3.如何使用scikit-learn和Keras库来自动对Python中的序列数据进行编码。

本教程分为4部分:

1.什么是One-Hot编码?

2.手动编写One-Hot编码

3.One-Hot Encode with scikit-learn.

4.One-Hot Encode with Keras.

1.什么是One-Hot编码?

One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。

One-Hot编码是分类变量作为二进制向量的表示。这首先要求将分类值映射到整数值。然后,每个整数值被表示为二进制向量,除了整数的索引之外,它都是零值,它被标记为1。

2.One-Hot编码的工作示例

让我们用一个小例子来说明一下到底什么是One-Hot编码。假设我们有一个带有’red’和’green’值的标签序列。我们可以将’red’的整数值分配为0,'green’的整数值为1。只要我们总是将这些数字分配给这些标签,这称为整数编码。一致性是重要的,所以我们可以稍后反转编码,并从整数值获取标签。

接下来,我们可以创建一个二进制向量来表示每个整数值。对于2个可能的整数值,向量的长度为2。

编码为0的“红色”标签将用二进制向量[1,0]表示,其中第0个索引被标记为值1。然后,编码为1的“绿色”标签将用一个二进制向量[0,1],其中第一个索引被标记为1。

如果我们有序列:

‘red’,‘red’,‘green’。

我们可以用整数编码来表示它:

0,0,1

而One-Hot编码就为:

1 [1, 0]

2 [1, 0]

3 [0, 1]

1.为什么要使用One-Hot编码?

One hot 编码进行数据的分类更准确,许多机器学习算法无法直接用于数据分类。数据的类别必须转换成数字,对于分类的输入和输出变量都是一样的。

我们可以直接使用整数编码,需要时重新调整。这可能适用于在类别之间存在自然关系的问题,例如温度“冷”(0)和”热“(1)的标签。

当没有关系时,可能会出现问题,一个例子可能是标签的“狗”和“猫”。

在这些情况下,我们想让网络更具表现力,为每个可能的标签值提供概率式数字。这有助于进行问题网络建模。当输出变量使用one-hot编码时,它可以提供比单个标签更准确的一组预测。

2.手动One Hot编码:

在这个例子中,我们将假设我们有一个字符串的例子,但是示例序列并不涵盖所有可能的例子。

我们将使用以下字符的输入序列:

Hello world。

我们将假设所有可能输入是小写字母和空格的完整字母表。因此,我们将以此展示如何滚动我们自己的one hot编码。

完整的示例如下所示。

from numpy import argmax
# define input string
data = 'hello world'
print(data)
# define universe of possible input values
alphabet = 'abcdefghijklmnopqrstuvwxyz '
# define a mapping of chars to integers
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# integer encode input data
integer_encoded = [char_to_int[char] for char in data]
print(integer_encoded)
# one hot encode
onehot_encoded = list()
for value in integer_encoded:
       letter = [0 for _ in range(len(alphabet))]
       letter[value] = 1
       onehot_encoded.append(letter)
print(onehot_encoded)
# invert encoding
inverted = int_to_char[argmax(onehot_encoded[0])]
print(inverted)

运行示例首先打印输入字符串。

所有可能的输入的映射都是从char值创建为整数值。然后使用该映射对输入字符串进行编码。我们可以看到输入’h’中的第一个字母被编码为7。然后将整数编码转换为one hot编码。一次完成一个整数编码的字符。创建0个值的列表,以便字母表的长度可以表示任何预期的字符的长度。

接下来,特定字符的索引标记为1。我们可以看到,编码为7的第一个字母“h”整数由二进制向量表示,长度为27,第七个索引标记为1。

最后,我们反转第一个字母的编码并打印结果。我们通过使用NumPy argmax()函数定位具有最大值的二进制向量中的索引,然后使用字符值的反向查找表中的整数进行整数。

注意:输出格式化为可读性(我们将空格默认设置为z)。

 	
 hello world

 [7, 4, 11, 11, 14, 26, 22, 14, 17, 11, 3]

 [[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 1, 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, 1, 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, 1, 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, 1, 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, 0, 0, 1],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

  h

现在我们已经看到了如何从头开始自己的one hot编码,我们来看看如何使用scikit学习库来对输入序列自动完全捕获输入值的预期范围的情况。

3.One-Hot Encode with scikit-learn:

在这个例子中,我们假设你有一个输出序列如下3个标签:

Cold,warm,hot

10个时间序列的示例顺序可以是:

Cold,cold,warm,cold,hot,hot,warm,cold,warm,hot

这将首先需要一个整数编码,如1,2,3,然后是整数到one hot编码具有3个值的二进制向量,例如[1,0,0]。

这个情况下提供序列中每个可能值的至少一个示例。因此,我们可以使用自动方法来定义整数到二进制向量的映射。

在这个例子中,我们将使用scikit学习库的编码器。具体来说,LabelEncoder创建标签的整数编码,OneHotEncoder用于创建整数编码值的one hot编码。

from numpy import array
from numpy import argmax
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
# define example
data = ['cold', 'cold', 'warm', 'cold', 'hot', 'hot', 'warm', 'cold', 'warm', 'hot']
values = array(data)
print(values)
# integer encode
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(values)
print(integer_encoded)
# binary encode
onehot_encoder = OneHotEncoder(sparse=False)
integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
print(onehot_encoded)
# invert first example
inverted = label_encoder.inverse_transform([argmax(onehot_encoded[0, :])])
print(inverted)

运行示例首先打印标签序列。之后是标签的整数编码,最后是one hot编码。训练数据包含所有可能示例的集合,因此我们可以依靠整数和one hot编码变换来创建标签到编码的完整映射。

默认情况下,OneHotEncoder类将返回更高效的稀疏编码,这可能不适用于某些应用程序。例如使用Keras深度学习库。在这种情况下,我们通过设置sparse = False这个参数来禁用稀疏返回类型。

首先,我们可以使用argmax()NumPy函数来找到具有最大值的列的索引。然后可以将其输入到LabelEncoder,以计算反向变换回文本标签。运行结果为:

['cold' 'cold' 'warm' 'cold' 'hot' 'hot' 'warm' 'cold' 'warm' 'hot'] 

[0 0 2 0 1 1 2 0 2 1]

[[ 1.  0.  0.]

 [ 1.  0.  0.]

 [ 0.  0.  1.]

 [ 1.  0.  0.]

 [ 0.  1.  0.]

 [ 0.  1.  0.]

 [ 0.  0.  1.]

 [ 1.  0.  0.]

 [ 0.  0.  1.]

 [ 0.  1.  0.]] 

['cold']

在下一个例子中,我们来看一下如何直接对一个整数值进行one hot编码。

4.One Hot Encode with Keras:

您可能有一个已经是整数编码的序列。

经过处理后,您可以直接使用整数。或者,您可以直接对整数进行one hot 编码。这是非常重要的如果整数没有真正的顺序关系并且只是标签的占位符。

Keras提供了一个名为to_categorical()的函数,它可以帮助你使用one hot编码整数数据。接下来我们看一个小例子:

在这个例子中,我们有4个整数值[0,1,2,3],我们有以下10个数字的输入序列:

Data = [1,3,2,0,3,2,2,1,0,1]

该序列具有已知了所有值,因此我们可以直接使用to_categorical()函数。以下列出了此功能的完整示例。

from numpy import array
from numpy import argmax
from keras.utils import to_categorical
# define example
data = [1, 3, 2, 0, 3, 2, 2, 1, 0, 1]
data = array(data)
print(data)
# one hot encode
encoded = to_categorical(data)
print(encoded)
# invert encoding
inverted = argmax(encoded[0])
print(inverted)

运行示例并打印输入序列。

然后将整数编码为二进制向量并打印。我们可以看到,正如我们预期的那样,第一个整数值1被编码为[0,1,0,0]。

然后,我们使用NumPy argmax()函数反转编码,该函数返回第一个整数的期望值1的序列中的第一个值。

[1 3 2 0 3 2 2 1 0 1]

[[ 0.  1.  0.  0.]

 [ 0.  0.  0.  1.]

 [ 0.  0.  1.  0.]

 [ 1.  0.  0.  0.]

 [ 0.  0.  0.  1.]

 [ 0.  0.  1.  0.]

 [ 0.  0.  1.  0.]

 [ 0.  1.  0.  0.]

 [ 1.  0.  0.  0.]

 [ 0.  1.  0.  0.]

原文链接:https://www.cnblogs.com/fujian-code/p/8717579.html

<think> 我们正在讨论One-Hot编码,用户可能希望了解其原理、实现方法以及在DataFrame数据集中的应用。 根据用户提供的引用,我们可以总结如下: 原理: - One-Hot编码将分类变量转换为二进制向量表示,每个类别对应一个二进制特征,取值为0或1。 - 对于具有n个不同类别的分类变量,One-Hot编码会创建n个新的二进制特征列。 - 每个样本在对应的类别列上标记为1,其他列标记为0。 实现方法(在DataFrame中): - 使用Pandas的`get_dummies()`函数是最常见的方法(引用[5])。 - 也可以使用scikit-learn的`OneHotEncoder`,特别是在机器学习流水线中。 - 在PyTorch中,可以使用`F.one_hot`或`torch.eye`(引用[4])。 应用场景: - 机器学习模型中无法直接处理文本标签,需要转换为数值形式(引用[1])。 - 处理非数值型数据,如国家、颜色等(引用[2])。 -深度学习中,One-Hot编码常用于标签处理(如分类任务中的目标变量)(引用[4])。 下面我们将详细展开,并提供在DataFrame中应用的示例。 </think> ### One-Hot编码原理与应用 #### 🧠 一、核心原理 One-Hot编码是将**分类变量**转换为**二进制向量**的技术,核心原理如下: 1. **离散化表示**:每个类别值映射为一个唯一的二进制向量 2. **单热点原则**:向量中仅有一个元素为1,其余为0 3. **维度扩展**:$k$个类别生成$k$维向量空间 数学表示为: $$ \text{对于类别} C = \{c_1, c_2, ..., c_k\} \quad \text{编码后向量} \quad v_i = [\delta_{i1}, \delta_{i2}, ..., \delta_{ik}] $$ 其中$\delta_{ij}$是Kronecker delta函数,当$i=j$时为1,否则为0[^3]。 #### ⚙️ 二、实现方法 ##### 1. Pandas实现(推荐) ```python import pandas as pd # 创建示例DataFrame data = {'电影类型': ['动作', '喜剧', '科幻', '喜剧', '动作']} df = pd.DataFrame(data) # One-Hot编码 one_hot = pd.get_dummies(df['电影类型'], prefix='类型') # 合并回原DataFrame df_encoded = pd.concat([df, one_hot], axis=1) print(df_encoded) ``` 输出: ``` 电影类型 类型_动作 类型_喜剧 类型_科幻 0 动作 1 0 0 1 喜剧 0 1 0 2 科幻 0 0 1 3 喜剧 0 1 0 4 动作 1 0 0 ``` ##### 2. Scikit-learn实现 ```python from sklearn.preprocessing import OneHotEncoder encoder = OneHotEncoder(sparse_output=False) encoded_array = encoder.fit_transform(df[['电影类型']]) # 转换为DataFrame df_sklearn = pd.DataFrame(encoded_array, columns=encoder.get_feature_names_out(['电影类型'])) ``` ##### 3. PyTorch实现 ```python import torch categories = {'动作':0, '喜剧':1, '科幻':2} category_idx = [categories[item] for item in df['电影类型']] # 生成One-Hot张量 one_hot_tensor = torch.nn.functional.one_hot( torch.tensor(category_idx), num_classes=3 ) ``` #### 📊 三、在DataFrame中的应用场景 | 应用场景 | 示例 | 优势 | |---------|------|------| | 分类特征处理 | 电影类型、导演国籍 | 消除类别间数值大小误导 | | 标签编码 | 情感分析中的正/负面标签 | 适配分类损失函数(如交叉熵) | | 特征工程 | 用户年龄段分段编码 | 增强模型非线性表达能力 | | 多标签分类 | 电影多重标签(动作/冒险/科幻) | 支持多标签表示 | **注意事项**: 1. **维度爆炸**:当类别数量过大时(>50),考虑使用嵌入层替代[^4] $$ \text{嵌入维度} \ll \text{类别数量} $$ 2. **稀疏性问题**:One-Hot向量通常高度稀疏,需配合稀疏矩阵处理技术 3. **类别未知**:测试集出现新类别时,需特殊处理(如归为"未知"类) #### 🔍 四、实战:电影数据集编码 ```python # 构建电影数据集 movie_data = { '电影名': ['肖申克的救赎', '阿甘正传', '盗梦空间'], '类型': ['剧情', '剧情/爱情', '科幻/动作'], '评分': [9.7, 9.5, 9.3] } df_movies = pd.DataFrame(movie_data) # 多标签One-Hot编码 genres_expanded = df_movies['类型'].str.get_dummies('/') df_final = pd.concat([df_movies, genres_expanded], axis=1) ``` 结果DataFrame包含新增列:`剧情`, `爱情`, `科幻`, `动作`,对应位置标记为1或0。 #### 💡 最佳实践建议 1. **前缀命名**:使用`prefix`参数明确特征来源(如`pd.get_dummies(prefix='类型')`) 2. **删除原列**:编码后建议删除原始分类列避免冗余 3. **处理NaN**:`pd.get_dummies(dummy_na=True)`可保留缺失值信息 4. **内存优化**:使用`sparse=True`参数节省内存(Scikit-learn) > One-Hot编码是处理分类变量的基础技术,能将非数值型数据转化为适合机器学习模型处理的格式,特别适用于逻辑回归、SVM等无法直接处理类别数据的算法[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值