在机器学习算法中,我们经常会遇到离散化的特征或标签。
one-hot编码,又称“独热编码”。其实就是用N位状态寄存器编码N个状态,每个状态都有独立的寄存器位,且这些寄存器位中只有一位有效,说白了就是只能有一个状态。
对于离散化标签进行onehot编码的原因,是因为如果仅仅对原始的离散标签,比如图数据集Cora数据集的标签(‘Genetic_Algorithms’, ‘Probabilistic_Methods’, ‘Reinforcement_Learning’, ‘Neural_Networks’, ‘Theory’, ‘Case_Based’, ‘Rule_Learning’),仅仅用(1,2,3,4,5,6,7)对labels进行编码,人为设定了各个标签样本的距离。
对于“距离”这个概念的理解:
举个例子来说,假设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]
简而言之,即:
这里先给出一个对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)