• 【NLP学习记录】One-Hot编码


    1. One-Hot编码概念

    one-hot编码的基本思想是将每个类别映射到一个向量,其中只有一个元素的值为1,其余元素的值为0。这样,每个类别之间相互独立,不存在顺序或距离关系。

    举例:对于三个类别的情况,可以使用如下的one-hot编码:

    • 类别1:[1,0,0]
    • 类别2:[0,1,0]
    • 类别3:[0,0,1]

    在深度学习中,神经网络的输入层通常使用one-hot编码来表示分类变量。这种编码方式可避免不必要的关系假设,还能清晰的输入表示,有助于模型的学习和泛化。

    2. 英文文本案例

    import torch
    import torch.nn.functional as F
    
    #示例文本
    texts = ['Hello, how are you? ','I am doing well, thank you! ','Goodbye.']
    
    #构建词汇表
    word_index = {}
    index_word = {}
    for i, word in enumerate(set("".join(texts).split())):
        word_index[word] = i
        index_word[i] = word
      
    #将文本转化为整数序列
    sequences = [[word_index[word]for word in text.split()] for text in texts]
    
    #获取词汇表大小
    vocab_size = len(word_index)
    
    #将整数序列转化为one-hot编码
    one_hot_results = torch.zeros(len(texts), vocab_size)
    for i, seq in enumerate (sequences):
        one_hot_results[i,seq] = 1
        
    #打印结果
    print("词汇表:")
    print(word_index)
    print("\n文本:")
    print(texts)
    print("\n文本序列:")
    print(sequences)
    print("\nOne-Hot编码:")
    print(one_hot_results)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    运行结果:
    在这里插入图片描述

    3. 中文文本案例

    import torch
    import torch.nn.functional as F
    
    #示例中文文本
    texts = ['你好,最近怎么样? ', '我过得很好,谢谢!', 'K同学啊']
    
    
    #构建词汇表
    word_index = {}
    index_word = {}
    for i, word in enumerate(set("".join(texts))):
        word_index[word] = i
        index_word[i] = word
    
    #将文本转化为整数序列
    sequences = [[word_index[word] for word in text] for text in texts]
    
    #获取词汇表大小
    vocab_size = len(word_index)
    
    #将整数序列转化为one-hot编码
    one_hot_results = torch.zeros(len(texts), vocab_size)
    for i,seq in enumerate(sequences):
        one_hot_results[i,seq] = 1
        
    #打印结果
    print("词汇表:")
    print(word_index)
    print("\n文本:")
    print(texts)
    print("\n文本序列:")
    print(sequences)
    print("\nOne-Hot编码:")
    print(one_hot_results)   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    运行结果
    在这里插入图片描述

    注意: 以上案例以字为基本单位,但词语被拆分后,显然失去原有的意思。在下面的案例中,我们将使用jieba分词工具对句子进行划分。

    使用结巴分词(jieba)进行中文文本的分词处理,然后将分词后的结果转化为one-hot编码。首先,确保你已经安装了结巴分词库:pip install jieba

    import torch
    import torch.nn.functional as F
    import jieba
    
    #示例中文文本
    texts = ['你好,最近怎么样? ', '我过得很好,谢谢!', '再见。']
    
    # 使用结巴分词进行分词
    tokenized_texts = [list(jieba.cut(text)) for text in texts]
    
    #构建词汇表
    word_index = {}
    index_word = {}
    for i, word in enumerate(set([word for text in tokenized_texts for word in text])):
        word_index[word] = i
        index_word[i] = word
    
    #将文本转化为整数序列
    sequences = [[word_index[word] for word in text] for text in tokenized_texts]
    
    #获取词汇表大小
    vocab_size = len(word_index)
    
    #将整数序列转化为one-hot编码
    one_hot_results = torch.zeros(len(texts), vocab_size)
    for i,seq in enumerate(sequences):
        one_hot_results[i,seq] = 1
        
    #打印结果
    print("词汇表:")
    print(word_index)
    print("\n文本:")
    print(texts)
    print("\n文本序列:")
    print(sequences)
    print("\nOne-Hot编码:")
    print(one_hot_results)    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    运行结果:
    在这里插入图片描述

    4. 任务

    • 任务要求:加载one-hot task.txt文件,并使用one-hot编码进行处理
    import torch
    import jieba
    #获取文件路径
    file_name = "D:\\Personal Data\\Learning Data\\DL Learning Data\\one-hot task.txt"
    # 从文本中读取文本行
    with open(file_name,"r",encoding = "utf-8") as file:
        context = file.read()
        sentences = context.split()
    # 使用jieba逐句分词
    tokenized_texts = [list(jieba.lcut(sentence)) for sentence in sentences]
    #构建词汇表
    word_index = {}
    index_word = {}
    for i, word in enumerate(set([word for text in tokenized_texts for word in text])):
        word_index[word] = i
        index_word[i] = word
        
    sequences = [[word_index[word] for word in text] for text in tokenized_texts]
    
    #获取词汇表大小
    vocab_size = len(word_index)
    
    #将整数序列转化为one-hot编码
    one_hot_results = torch.zeros(len(sentences), vocab_size)
    for i,seq in enumerate(sequences):
        one_hot_results[i,seq] = 1
        
    #打印核对结果
    print("====词汇表:====\n", word_index)
    print("====文本:====\n", sentences)
    print("====分词结果:====\n", tokenized_texts)
    print("====文本序列:====\n",sequences)
    print("====One-Hot编码:====\n", one_hot_results)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    运行结果:

    ====词汇表:====
     {'到': 0, '是': 1, 'hot': 2, '三个': 3, '情况': 4, '为': 5, '这些': 6, '不': 7, '值': 8, ':': 9, '可能': 10, '对于': 11, ')': 12, '独立': 13, '具有': 14, '独热': 15, '将': 16, '称': 17, '距离': 18, '和': 19, '编码方式': 20, '可以': 21, '-': 22, '一个': 23, '错误': 24, '思想': 25, '只有': 26, '3': 27, '地': 28, '例如': 29, '使用': 30, '提到': 31, '这': 32, '用': 33, '1': 34, '分别': 35, '为了': 36, '其余': 37, '一些': 38, '避免': 39, '基本': 40, '有': 41, '这种': 42, '关系': 43, '问题': 44, '也': 45, '之间': 46, ',': 47, '每个': 48, '序列': 49, '元素': 50, '(': 51, '采用': 52, '。': 53, '或': 54, '2': 55, '上面': 56, '模型': 57, '的': 58, 'one': 59, '相互': 60, '字典': 61, '顺序': 62, '而': 63, '实际上': 64, '了': 65, '表示': 66, '存在': 67, '、': 68, '或者': 69, '会': 70, '但是': 71, '引入': 72, '比较': 73, '其中': 74, '实际意义': 75, '就是': 76, '认为': 77, '不同': 78, '向量': 79, '编码': 80, '直观': 81, '类别': 82, '这样': 83, '如下': 84, '映射': 85, '0': 86}
    ====文本:====
     ['比较直观的编码方式是采用上面提到的字典序列。例如,对于一个有三个类别的问题,可以用1、2和3分别表示这三个类别。但是,这种编码方式存在一个问题,就是模型可能会错误地认为不同类别之间存在一些顺序或距离关系,而实际上这些关系可能是不存在的或者不具有实际意义的。', '为了避免这种问题,引入了one-hot编码(也称独热编码)。one-hot编码的基本思想是将每个类别映射到一个向量,其中只有一个元素的值为1,其余元素的值为0。这样,每个类别之间就是相互独立的,不存在顺序或距离关系。例如,对于三个类别的情况,可以使用如下的one-hot编码:']
    ====分词结果:====
     [['比较', '直观', '的', '编码方式', '是', '采用', '上面', '提到', '的', '字典', '序列', '。', '例如', ',', '对于', '一个', '有', '三个', '类别', '的', '问题', ',', '可以', '用', '1', '、', '2', '和', '3', '分别', '表示', '这', '三个', '类别', '。', '但是', ',', '这种', '编码方式', '存在', '一个', '问题', ',', '就是', '模型', '可能', '会', '错误', '地', '认为', '不同', '类别', '之间', '存在', '一些', '顺序', '或', '距离', '关系', ',', '而', '实际上', '这些', '关系', '可能', '是', '不', '存在', '的', '或者', '不', '具有', '实际意义', '的', '。'], ['为了', '避免', '这种', '问题', ',', '引入', '了', 'one', '-', 'hot', '编码', '(', '也', '称', '独热', '编码', ')', '。', 'one', '-', 'hot', '编码', '的', '基本', '思想', '是', '将', '每个', '类别', '映射', '到', '一个', '向量', ',', '其中', '只有', '一个', '元素', '的', '值', '为', '1', ',', '其余', '元素', '的', '值', '为', '0', '。', '这样', ',', '每个', '类别', '之间', '就是', '相互', '独立', '的', ',', '不', '存在', '顺序', '或', '距离', '关系', '。', '例如', ',', '对于', '三个', '类别', '的', '情况', ',', '可以', '使用', '如下', '的', 'one', '-', 'hot', '编码', ':']]
    ====文本序列:====
     [[73, 81, 58, 20, 1, 52, 56, 31, 58, 61, 49, 53, 29, 47, 11, 23, 41, 3, 82, 58, 44, 47, 21, 33, 34, 68, 55, 19, 27, 35, 66, 32, 3, 82, 53, 71, 47, 42, 20, 67, 23, 44, 47, 76, 57, 10, 70, 24, 28, 77, 78, 82, 46, 67, 38, 62, 54, 18, 43, 47, 63, 64, 6, 43, 10, 1, 7, 67, 58, 69, 7, 14, 75, 58, 53], [36, 39, 42, 44, 47, 72, 65, 59, 22, 2, 80, 51, 45, 17, 15, 80, 12, 53, 59, 22, 2, 80, 58, 40, 25, 1, 16, 48, 82, 85, 0, 23, 79, 47, 74, 26, 23, 50, 58, 8, 5, 34, 47, 37, 50, 58, 8, 5, 86, 53, 83, 47, 48, 82, 46, 76, 60, 13, 58, 47, 7, 67, 62, 54, 18, 43, 53, 29, 47, 11, 3, 82, 58, 4, 47, 21, 30, 84, 58, 59, 22, 2, 80, 9]]
    ====One-Hot编码:====
     tensor([[0., 1., 0., 1., 0., 0., 1., 1., 0., 0., 1., 1., 0., 0., 1., 0., 0., 0.,
             1., 1., 1., 1., 0., 1., 1., 0., 0., 1., 1., 1., 0., 1., 1., 1., 1., 1.,
             0., 0., 1., 0., 0., 1., 1., 1., 1., 0., 1., 1., 0., 1., 0., 0., 1., 1.,
             1., 1., 1., 1., 1., 0., 0., 1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 1.,
             0., 1., 0., 1., 1., 1., 1., 0., 0., 1., 1., 0., 0., 0., 0.],
            [1., 1., 1., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.,
             1., 0., 0., 1., 1., 1., 0., 1., 1., 0., 0., 1., 1., 0., 0., 0., 1., 0.,
             1., 1., 0., 1., 1., 0., 1., 1., 1., 1., 1., 1., 1., 0., 1., 1., 0., 1.,
             1., 0., 0., 0., 1., 1., 1., 0., 1., 0., 0., 1., 0., 1., 0., 0., 0., 0.,
             1., 0., 1., 0., 1., 0., 0., 1., 1., 0., 1., 1., 1., 1., 1.]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    5. 总结

    • 文本的基本处理流程:1. 将文本分割为句子 2. 将句子分割为词 3. 对词进行编码
    • one-hot编码的适用场景:特征之间相互独立,且特征数量较少
  • 相关阅读:
    LabVIEW进行MQTT通信及数据解析
    UE4 WebUI插件使用指南
    如何在Appium中使用AI定位
    QQ邮箱怎么设置SMTP接口服务器?
    建立ISO27001,能给企业带来哪些好处?
    微服务配置中心
    基于pam实现的批量执行命令工具-Cyberark
    vue3与vue2之全局变量的使用
    windows安装composer并更换国内镜像
    包管理工具npm和Yarn的区别,我们该如何选择?
  • 原文地址:https://blog.csdn.net/Elfin_z/article/details/136750487