Python,Keras深度学习中非连续的字母怎么处理为one-hot编码

Posted 程序媛一枚~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python,Keras深度学习中非连续的字母怎么处理为one-hot编码相关的知识,希望对你有一定的参考价值。

Python,Keras深度学习中非连续的字母怎么处理为one-hot编码

写这篇博客源于博友的提问,将介绍Python,Keras深度学习中非连续的字母文本怎么处理为one-hot编码。

初始值是

1. 效果图

首先对字母转数字,然后字母计算相对应的one-hot对应的值,不一定是 A-Z所有的字母都有,转换one-hot,效果图如下:

原始数据为 (66,11)66行,每行11个字母(字母从A-Y),最小值为A,最大值为Y,唯一的字母总数为20个。
转换为(66,11,20)

2. 源码

# python 将字母A-Z 转数字,并且转换为one-hot编码
import numpy as np
import pandas as pd  # pd.read_excel()方法读取excel文件


# 预处理数据【找到所有的字母类型并对应0~ len(字母数)-1,然后进行转换】
# 按照此关系对应:{'A': 0, 'C': 1, 'D': 2, 'E': 3, 'F': 4, 'G': 5, 'H': 6, 'I': 7, 'K': 8, 'L': 9, 'M': 10, 'N': 11, 'P': 12, 'Q': 13, 'R': 14, 'S': 15, 'T': 16, 'V': 17, 'W': 18, 'Y': 19}
# 字母转数字  如 Y G Q E M Y V F R S E  转成 [19, 5, 13, 3, 10, 19, 17, 4, 14, 15, 3]
# 并转换为one-hot编码 (60,11) 转成 (60,11,20)
# 如     [[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]  第一行代表的Y值
#         [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. 1. 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. 1.]
#         [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 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. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
def preprocess_test_data(df_train):
    print(type(df_train['文本']))
    # 转换pd dataframe为 numpy,并获取x值
    np_df_train = np.array(df_train['文本'])
    print('origin: ', np_df_train[0])

    # 找到所有字母的分类及从0开始对应的字母标签值
    # {'A': 0, 'C': 1, 'D': 2, 'E': 3, 'F': 4, 'G': 5, 'H': 6, 'I': 7, 'K': 8, 'L': 9, 'M': 10, 'N': 11, 'P': 12, 'Q': 13, 'R': 14, 'S': 15, 'T': 16, 'V': 17, 'W': 18, 'Y': 19}
    # 注意 如果按照 A: 0  B:1 则转换的时候需要 A~Y 转成 24个字符表示,但此处需要表示为20个字符
    # 所以需要计算一个差值
    data_labels = sorted(
        set(np.array(sum([[j for j in list(str(i).replace(" ", ''))] for i in np_df_train], [])).flatten()))
    dict_lables = {}
    dict_labels_subtract = {}
    for index, j in enumerate(data_labels):
        dict_lables[j] = index
        dict_labels_subtract[j] = ord(j) - ord('A') - index
    print('data_labels: ', data_labels)
    print('dict_labels: ', dict_lables)
    print('dict_labels_subtract: ', dict_labels_subtract, len(dict_labels_subtract.keys()))
    
    print('min,max,count',min(dict_lables.keys()),max(dict_lables.keys()),len(dict_lables.keys()))

    # x = [[ord(j) - ord('A') for j in list(str(i).replace(" ", ''))] for i in np_df_train]
    # 转换每一个字母为 数字,按照A对应0  C对应1  D对应2 E对应3 Y对应19
    x = [[ord(j) - ord('A') - dict_labels_subtract[j] for j in list(str(i).replace(" ", ''))] for i in np_df_train]
    print('x[0]: ', x[0], type(x))

    # list转array
    labels = np.array(x)
    # 记录下数据原始的维度,方便进行one-hot编码后转回去
    labels_width, labels_height = labels.shape
    print('labels shape: ', labels.shape)
    set_n = sorted(set(labels.flatten()))
    print('sorted set_n: ', sorted(set_n), len(set_n), min(set_n), max(set_n))

    # 进行one-hot编码
    res = np.eye(len(set_n))[labels.flatten()]
    print("labels转成one-hot形式的结果:\\n", res[0], "\\n")
    print("labels转化成one-hot后的大小:", res.shape)

    # 成功实现one-hot编码 (60, 11)  -->  (60, 11, 20)
    train_data = res.reshape(labels_width, labels_height, len(set_n))
    print('转回原始数据的形式:', train_data[0], train_data.shape)
    return train_data


# 构建原始数据
test_dict = {'文本': ['Y G Q E M Y V F R S E', 'A K E W G Y A D H N G', 'S E P K Y Y S Q P I L', 'A L A K N Y P G K K V',
                    'S P Y S D Y G G R K D', 'A K V K S Y K R Q A E', 'Q L P H D Y C T T P G', 'A T D S R Y G Q K E S',
                    'K I K Q Y Y Q K F T W', 'D E T E T Y Q E K V H', 'L E V T A Y S P L G S', 'Q G Y H S Y A V R T A',
                    'T A K G D Y P L E A V', 'S E G S E Y E E I P K', 'S S G S P Y G G G Y G', 'S L G E E Y T E D Y G',
                    'K S M S V Y C T P N K', 'P K S Q R Y S G A Y G', 'A N Y S S Y L A K A D', 'K R I H E Y K P F K T',
                    'K D L F D Y S P P L H', 'S Y P E V Y Q E R F P', 'A P S P V Y G S S A K', 'V W L R R Y L E F A G',
                    'A Y F G V Y D T A K G', 'V N P E Q Y S K R F N', 'E M L F I Y S H Y K Q', 'Y R A Y D Y H E E T R',
                    'S L D R G Y T S D S E', 'L C M H K Y L L I Q S', 'R V G N E Y V T K G Q', 'P R A E W Y R D D V L',
                    'P R L S I Y G R S P D', 'V K E L T Y Q T E E D', 'V L A M P Y D T P V P', 'I K E L T Y Q T E E D',
                    'K V K N A Y E E S L D', 'T R L G I Y T V L F E', 'D S Y D P Y D F S D T', 'V L R A D Y V K E M L',
                    'N G C I N Y E A F V K', 'E E C L A Y F G V S E', 'A V G H G Y Y M A A G', 'P A A H L Y F S Q S C',
                    'S P P G P Y G Q E M Y', 'T K I A L Y E T P T G', 'N Q E D I Y I T T E S', 'T L D N A Y M E K C D',
                    'P E G Q N Y S S E L H', 'K V Q V E Y K G E T K', 'Y G K S L Y H D I T G', 'N S D S I Y S S T P E',
                    'S S V P E Y V Y N L H', 'N T K T S Y H T P G D', 'K N R P G Y V S E E E', 'E E P S E Y T D E E D',
                    'I M D N A Y F C E A D', 'G D R S G Y S S P G S', 'L S E D E Y Y S E E E', 'N I F F D Y S G R D L'],
             '标签': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}

# 手动构建pandas.DataFrame
# 方法1:直接写入赋值
df_train = pd.DataFrame(test_dict)

# 方法2:字典型赋值
# df_train = pd.DataFrame(data=test_dict)
print(type(df_train), df_train[:1])

# 预处理数据【找到所有的字母类型并对应0~ len(字母数)-1,然后进行转换】
# 按照此关系对应:{'A': 0, 'C': 1, 'D': 2, 'E': 3, 'F': 4, 'G': 5, 'H': 6, 'I': 7, 'K': 8, 'L': 9, 'M': 10, 'N': 11, 'P': 12, 'Q': 13, 'R': 14, 'S': 15, 'T': 16, 'V': 17, 'W': 18, 'Y': 19}
# 字母转数字  如 Y G Q E M Y V F R S E  转成 [19, 5, 13, 3, 10, 19, 17, 4, 14, 15, 3]
# 并转换为one-hot编码 (60,11) 转成 (60,11,20)
# 如     [[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]  第一行代表的Y值
#         [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. 1. 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. 1.]
#         [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 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. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
train_data = preprocess_test_data(df_train)
print('Shape of data train:', train_data.shape)

参考

以上是关于Python,Keras深度学习中非连续的字母怎么处理为one-hot编码的主要内容,如果未能解决你的问题,请参考以下文章

学习参考+《深度学习基于Keras的Python实践》PDF+ 源代码+魏贞原

学习Keras:《Keras快速上手基于Python的深度学习实战》PDF代码+mobi

Keras深度学习实战——房价预测

Keras:Python深度学习库简介

Keras:Python深度学习库简介

分享《Keras快速上手:基于Python的深度学习实战》+PDF+谢梁