[数据预处理] onehot编码:是什么,为什么,怎么样

[数据预处理] onehot编码:是什么,为什么,怎么样

文章目录

  • [数据预处理] onehot编码:是什么,为什么,怎么样
      • 什么是onehot编码
      • 为什么要进行onehot编码
        • 对labels进行onehot编码的原因
        • 对特征进行onehot编码的原因
      • 如何进行onehot编码

什么是onehot编码

在机器学习算法中,我们经常会遇到离散化的特征或标签

one-hot编码,又称“独热编码”。其实就是用N位状态寄存器编码N个状态,每个状态都有独立的寄存器位,且这些寄存器位中只有一位有效,说白了就是只能有一个状态


为什么要进行onehot编码

对labels进行onehot编码的原因

对于离散化标签进行onehot编码的原因,是因为如果仅仅对原始的离散标签,比如图数据集Cora数据集的标签(‘Genetic_Algorithms’, ‘Probabilistic_Methods’, ‘Reinforcement_Learning’, ‘Neural_Networks’, ‘Theory’, ‘Case_Based’, ‘Rule_Learning’),仅仅用(1,2,3,4,5,6,7)对labels进行编码,人为设定了各个标签样本的距离

对于“距离”这个概念的理解:

  • 其一,参照度量学习的知识,各类样本 sample 之间的相似度由 embedding domain 内的距离来度量。若以1,2,3,4,5,6,7)对labels进行编码,则1和2的距离要小于1和5之间的距离,而这种类别之间的距离是人为给定的,没有道理的
  • 其二,就在于计算loss的时候。loss一般用距离来表示,如果用1~5来表示,那么1和2的距离时1,而1和5的距离时4,但是按道理1和2、1和5的距离应该一样。如果用onehot编码表示,那么1和2的距离跟1和5的距离时一样的。

对特征进行onehot编码的原因

举个例子来说,假设4个样本,3种特征:

feature1 feature2 feature3
sample1 1 4 3
sample2 2 3 2
sample3 1 2 2
sample4 2 1 1

以1->001,2->010,3->100进行onehot编码,得到的结果是:

feature1 feature2 feature3
sample1 01 1000 100
sample2 10 0100 010
sample3 01 0010 010
sample4 10 0001 001

得到的feature向量就成了:

sample1 -> [0,1,1,0,0,0,1,0,0]

sample2 -> [1,0,0,1,0,0,0,1,0]

sample3 -> [0,1,0,0,1,0,0,1,0]

sample4 -> [1,0,0,0,0,1,0,0,1]

简而言之,即:

  • 解决了分类器处理离散数据困难的问题
  • 一定程度上起到了扩展特征的作用(上例中从3扩展到了9)

如何进行onehot编码

这里先给出一个对labels进行onehot编码的Demo:

from pygcn.utils import encode_onehot
import numpy as np

'''labels的onehot编码,前后结果对比'''
# 读取原始数据集
path="C:/Users/73416/PycharmProjects/PyGCN_Visualization/data/cora/"
dataset = "cora"
idx_features_labels = np.genfromtxt("{}{}.content".format(path, dataset),
                                        dtype=np.dtype(str))

RawLabels=idx_features_labels[:, -1]
print("原始论文类别(label):\n",RawLabels)
# ['Neural_Networks' 'Rule_Learning' 'Reinforcement_Learning' ...
# 'Genetic_Algorithms' 'Case_Based' 'Neural_Networks']
print(len(RawLabels))       # 2708

classes = set(RawLabels)       # set() 函数创建一个无序不重复元素集
print("原始标签的无序不重复元素集\n", classes)
# {'Genetic_Algorithms', 'Probabilistic_Methods', 'Reinforcement_Learning', 'Neural_Networks', 'Theory', 'Case_Based', 'Rule_Learning'}


# enumerate()函数生成序列,带有索引i和值c。
# 这一句将string类型的label变为onehot编码的label,建立映射关系
classes_dict = {c: np.identity(len(classes))[i, :] for i, c in
                    enumerate(classes)}
print("原始标签与onehot编码结果的映射字典\n",classes_dict)
#  {'Genetic_Algorithms': array([1., 0., 0., 0., 0., 0., 0.]), 'Probabilistic_Methods': array([0., 1., 0., 0., 0., 0., 0.]),
#   'Reinforcement_Learning': array([0., 0., 1., 0., 0., 0., 0.]), 'Neural_Networks': array([0., 0., 0., 1., 0., 0., 0.]),
#   'Theory': array([0., 0., 0., 0., 1., 0., 0.]), 'Case_Based': array([0., 0., 0., 0., 0., 1., 0.]),
#   'Rule_Learning': array([0., 0., 0., 0., 0., 0., 1.])}

# map() 会根据提供的函数对指定序列做映射。
# 这一句将string类型的label替换为onehot编码的label
labels_onehot = np.array(list(map(classes_dict.get, RawLabels)),
                             dtype=np.int32)
print("onehot编码的论文类别(label):\n",labels_onehot)
# [[0 0 0... 0 0 0]
#  [0 0 0... 1 0 0]
#  [0 1 0 ... 0 0 0]
#  ...
#  [0 0 0 ... 0 0 1]
#  [0 0 1 ... 0 0 0]
#  [0 0 0 ... 0 0 0]]
print(labels_onehot.shape)
# (2708, 7)

你可能感兴趣的:(数据预处理,图卷积神经网络,高光谱图像分类,python,机器学习,深度学习,人工智能,数据分析)