- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
目录
- one-hot编码
- 优点
- 缺点
- 英文文本案例
- 中文文本案例
- 中文结巴分词示例
- 作业
- 心得体会
one-hot编码
自然语言处理(NLP)入门,绕不开的第一个概念就是词向量。
文字对于计算机来说仅仅只是一个一个的符号,计算机是没有办法理解其中的含义的,计算也没有办法直接处理字符,因此,NLP任务的第一步就是:将文本数字化。
最早期的文本数字化方法,就是将文本转换为字典序列。如:阿 在新华字典中排第一,所以它的字典序列就是1。
但是使用字典序列有缺点,就是模型可能会错误地认为不同类型之间存在一些顺序或距离关系,而实际上这些关系可能是不存在或者不具有实际意义的。
为了避免这种问题,引入了one-hot编码(也称为独热编码)。
one-hot编码的基本思想是将每个类别映射到一个向量,其中只有一个元素的值为1,剩下的全部为0。这样,每个类别之间是相互独立的,不存在顺序或者距离关系。例如:三个不同的类别被标记为
- [1, 0, 0]
- [0, 1, 0]
- [0, 0, 1]
这种表示方式有助于模型更好地理解文本的含义。在深度学习中,神经网络的输入层通常使用one-hot编码来表示分类变量。这种编码方式不仅能够避免不必要的关系假设,还能够提供清晰的输入表示,有助于模型的学习和泛化。
优点
- 解决了分类器不好处理离散数据的问题,能够处理非连续型数值特征
缺点
- 在文本表征表示上有些缺点非常突出,首先one-hot编码是一个词袋模型,是不考虑词和词之间的顺序问题,它是假设词和词之间是相互独立的,但是大部分情况下词和词之间是相互影响的
- one-hot编码得到的特征是离散稀疏的,每个单词的one-hot编码维度是整个词汇表的大小,维度非常巨大,编码稀疏,会使计算代价变大。
英文文本案例
import torch
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)
中文文本案例
import torch
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]
# 获取词汇表大小x
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)
中文结巴分词示例
import torch
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)
作业
import torch
import jieba
# 读取文本
texts = open('任务文件.txt', 'r').read().split('\n')
# 使用结巴分词
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)
心得体会
通过本节的学习学会了如何将文本转换为one-hot编码,但是也发现在中文自然语言处理中,使用one-hot编码是有局限性的,通过使用结巴分词来进行分词处理,然后再转换为one-hot编码,可以获得比较简短的词向量。不过结巴分词好像不是基于人工智能的理解来分词,感觉他的准确度应该不是很稳定,也许使用AI模型来进行分词也是一种解决方案。