>- **🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/rbOOmire8OocQ90QM78DRA) 中的学习记录博客** >- **🍖 原作者:[K同学啊 | 接辅导、项目定制](https://mtyjkh.blog.csdn.net/)**
1.one-hot编码概念
想学习NLP绕不开的第一个概念就是词向量。什么是词向量,这个东西又是做什么用的呢?
文字对于计算机来说就仅仅只是一个个文字,计算机无法理解其中含义,更无法处理。因此,NLP第一步就是:将 文字 转换为计算机能看懂的 数字。在自然语言处理中最早期的方式就是将文本转换为字典序列:
如:“阿” 是新华字典中第1个单词 ,所以它的字典序列就是 1 。
词典中的第几个字
比较直观的编码方式是采用上面提到的字典序列。例如,对于一个有三个类别的问题,可以用1、2和3分别表示这三个类别。但是,这种编码方式存在一个问题,就是模型可能会错误地认为不同类别之间存在一些顺序或距离关系,而实际上这些关系可能是不存在的或者不具有实际意义的。
为了避免这种问题,引入了one-hot编码(也称独热编码)。one-hot编码的基本思想是将每个类别映射到一个向量,其中只有一个元素的值为1,其余元素的值为0。这样,每个类别之间就是相互独立的,不存在顺序或距离关系。例如,对于三个类别的情况,可以使用如下的one-hot编码:
●类别1:[1, 0, 0]
●类别2:[0, 1, 0]
●类别3:[0, 0, 1]
这样的表示方式有助于模型更好地理解文本含义。在深度学习中,神经网络的输入层通常使用one-hot编码来表示分类变量。这种编码方式不仅能够避免不必要的关系假设,还能够提供清晰的输入表示,有助于模型的学习和泛化。
例如:
John likes to watch movies. Mary likes too
John also likes to watch football games.
以上两句可以构造一个词典:
{"John": 1, "likes": 2, "to": 3, "watch": 4, "movies": 5, "also": 6, "football": 7, "games": 8, "Mary": 9, "too": 10}
one-hot可表示为:
John: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
likes: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
.......等等,以此类推。
1one-hot优点:
○解决了分类器不好处理离散数据的问题,能够处理非连续型数值特征。
2one-hot缺点:
○在文本表征表示上有些缺点非常突出,首先one-hot 编码是一个词袋模型,是不考虑词和词之间的顺序问题,它是假设词和词之间是相互独立的,但是在大部分情况下词和词之间是相互影响的。
○one-hot编码得到的特征是离散稀疏的,每个单词的one-hot编码维度是整个词汇表的大小,维度非常巨大,编码稀疏,会使得计算代价变大。
2. 中文文本文案例
注意使用结巴分词(jieba)进行中文文本的分词处理,然后将分词后的结果转化为one-hot编码。首先,确保你已经安装了结巴分词库:pip install jieba
import torch
import torch.nn.functional as F
import jieba
texts = ['比较直观的编码方式是采用上面提到的字典序列。例如,对于一个有三个类别的问题,可以用1、2和3分别表示这三个类别。但是,这种编码方式存在一个问题,就是模型可能会错误地认为不同类别之间存在一些顺序或距离关系,而实际上这些关系可能是不存在的或者不具有实际意义的。为了避免这种问题,引入了one-hot编码(也称独热编码)。one-hot编码的基本思想是将每个类别映射到一个向量,其中只有一个元素的值为1,其余元素的值为0。这样,每个类别之间就是相互独立的,不存在顺序或距离关系。例如,对于三个类别的情况,可以使用如下的one-hot编码']
#使用结巴分词
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(tokenized_texts)
print("\n 文本序列:")
print(sequences)
print("\n One-hot 编码:")
print(one_hot_results)
以下是运行结果
词汇表:
{'具有': 0, '这种': 1, '值': 2, '-': 3, '三个': 4, '直观': 5, '而': 6, '。': 7, '3': 8, '独立': 9, '比较': 10, '顺序': 11, '不': 12, 'one': 13, ')': 14, '字典': 15, '引入': 16, '关系': 17, '存在': 18, '编码方式': 19, '映射': 20, '如下': 21, ',': 22, '序列': 23, '类别': 24, '上面': 25, '也': 26, '的': 27, '会': 28, '基本': 29, '模型': 30, '其中': 31, '只有': 32, '相互': 33, '了': 34, '为了': 35, '对于': 36, '0': 37, '这': 38, 'hot': 39, '编码': 40, '可能': 41, '就是': 42, '元素': 43, '是': 44, '避免': 45, '独热': 46, '使用': 47, '这样': 48, '之间': 49, '思想': 50, '但是': 51, '、': 52, '提到': 53, '(': 54, '地': 55, '为': 56, '例如': 57, '认为': 58, '表示': 59, '不同': 60, '或者': 61, '情况': 62, '采用': 63, '距离': 64, '实际意义': 65, '到': 66, '1': 67, '将': 68, '其余': 69, '用': 70, '分别': 71, '向量': 72, '这些': 73, '2': 74, '实际上': 75, '或': 76, '称': 77, '可以': 78, '和': 79, '有': 80, '错误': 81, '问题': 82, '一个': 83, '一些': 84, '每个': 85}
文本:
['比较直观的编码方式是采用上面提到的字典序列。例如,对于一个有三个类别的问题,可以用1、2和3分别表示这三个类别。但是,这种编码方式存在一个问题,就是模型可能会错误地认为不同类别之间存在一些顺序或距离关系,而实际上这些关系可能是不存在的或者不具有实际意义的。为了避免这种问题,引入了one-hot编码(也称独热编码)。one-hot编码的基本思想是将每个类别映射到一个向量,其中只有一个元素的值为1,其余元素的值为0。这样,每个类别之间就是相互独立的,不存在顺序或距离关系。例如,对于三个类别的情况,可以使用如下的one-hot编码']
分词结果:
[['比较', '直观', '的', '编码方式', '是', '采用', '上面', '提到', '的', '字典', '序列', '。', '例如', ',', '对于', '一个', '有', '三个', '类别', '的', '问题', ',', '可以', '用', '1', '、', '2', '和', '3', '分别', '表示', '这', '三个', '类别', '。', '但是', ',', '这种', '编码方式', '存在', '一个', '问题', ',', '就是', '模型', '可能', '会', '错误', '地', '认为', '不同', '类别', '之间', '存在', '一些', '顺序', '或', '距离', '关系', ',', '而', '实际上', '这些', '关系', '可能', '是', '不', '存在', '的', '或者', '不', '具有', '实际意义', '的', '。', '为了', '避免', '这种', '问题', ',', '引入', '了', 'one', '-', 'hot', '编码', '(', '也', '称', '独热', '编码', ')', '。', 'one', '-', 'hot', '编码', '的', '基本', '思想', '是', '将', '每个', '类别', '映射', '到', '一个', '向量', ',', '其中', '只有', '一个', '元素', '的', '值', '为', '1', ',', '其余', '元素', '的', '值', '为', '0', '。', '这样', ',', '每个', '类别', '之间', '就是', '相互', '独立', '的', ',', '不', '存在', '顺序', '或', '距离', '关系', '。', '例如', ',', '对于', '三个', '类别', '的', '情况', ',', '可以', '使用', '如下', '的', 'one', '-', 'hot', '编码']]
文本序列:
[[10, 5, 27, 19, 44, 63, 25, 53, 27, 15, 23, 7, 57, 22, 36, 83, 80, 4, 24, 27, 82, 22, 78, 70, 67, 52, 74, 79, 8, 71, 59, 38, 4, 24, 7, 51, 22, 1, 19, 18, 83, 82, 22, 42, 30, 41, 28, 81, 55, 58, 60, 24, 49, 18, 84, 11, 76, 64, 17, 22, 6, 75, 73, 17, 41, 44, 12, 18, 27, 61, 12, 0, 65, 27, 7, 35, 45, 1, 82, 22, 16, 34, 13, 3, 39, 40, 54, 26, 77, 46, 40, 14, 7, 13, 3, 39, 40, 27, 29, 50, 44, 68, 85, 24, 20, 66, 83, 72, 22, 31, 32, 83, 43, 27, 2, 56, 67, 22, 69, 43, 27, 2, 56, 37, 7, 48, 22, 85, 24, 49, 42, 33, 9, 27, 22, 12, 18, 11, 76, 64, 17, 7, 57, 22, 36, 4, 24, 27, 62, 22, 78, 47, 21, 27, 13, 3, 39, 40]]
One-hot 编码:
tensor([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])