深度学习38:RNN前置知识:基础知识,词向量和词嵌入

目录标题

一、自然语言处理概述

我们平日使用的语言,如汉语或英语,称为自然语言。自然语言处理(Natural Language Processing,NLP)的目标就是让计算机理解人类语言,进而完成对我们有帮助的事情。

说到计算机可以理解的语言,我们可能会想到编程语言或者标记语言等。这些语言的语法定义可以唯一性地解释代码含义,计算机也能根据确定的规则分析代码。编程语言是一种机械的、缺乏活力的语言。换句话说,它是一种"硬语言"。而汉语或英语等自然语言是"软语言",其含义和形式会灵活变化,并且会不断出现新的词语或新的含义。要让计算机去理解自然语言,使用常规方法是无法办到的。下面是几个解决方法

1、基于同义词词典的方法

具有相同(同义词)或类似(近义词)含义的单词,可以归到同一个类别中;而根据单词"整体-部分"或者"上位-下位"关系,可以构建出层级的树状图。

这样,就可以构成一个庞大的"单词网络",用它就可以教会计算机单词之间的关系,从而计算出单词的"相似度"。

主要缺点:

  • 需要人工逐个定义单词之间的相关性,非常费时费力;
  • 新词不断出现,语言不断变化,词典维护成本极高;
  • 在表现力上也有限制。
2、基于计数的方法

大量的文本数据,构成了 语料库(corpus)。

我们的目的,就是从语料库中,自动且高效地提取出语言的"本质"。最简单的做法,就是统计"词频"

  • 分词:对词进行统计,首先需要对文本内容进行切分,找出一个个基本单元
  • 词关联ID:给单词标上一个 ID,构建单词和ID的关联字典(称为"词表")
  • 词向量化:用一个固定长度的向量来表示单词,也称为词的"分布式表示"

对每一个词,可以统计它周围出现了什么单词、出现了多少次(称为"上下文");把这些词频统计出来,就构成了一个向量;这个向量就可以表示当前的词了,称为"词向量"(word vector)。这样,所有词对应的向量,汇总起来就是一个矩阵,被称为 共现矩阵(co-occurrence matrix)。

主要缺点

对所有词进行向量化表示的计算复杂度极高。

3、基于推理的方法

除了基于计数的方法,还可以使用推理的方法把词用向量表示出来。

我们希望在已知上下文的前提下,"推测"当前位置的词是什么。

利用神经网络,接收上下文信息作为输入,通过模型计算,输出各个单词可能得出现概率;从而就可以根据上下文,预测该出现的单词了。

二、词嵌入层

什么是词嵌入

自然语言是由文字构成的,而语言的含义是由单词构成的。即单词是含义的最小单位。因此为了让计算机理解自然语言,首先要让它理解单词含义。

词向量是用于表示单词意义的向量,也可以看作词的特征向量。将词映射到向量的技术称为 词嵌入(Word Embedding)。

还有一种使用向量表示单词意义的方式是独热向量,独热向量很容易构建,但它们通常不是一个好的选择。一个主要原因是独热向量不能准确表达不同词之间的相似度。比如使用余弦相似度 x T y ∣ ∣ x ∣ ∣ ∣ ∣ y ∣ ∣ \frac{x^Ty}{||x|| ||y||} ∣∣x∣∣∣∣y∣∣xTy 来表示两个词之间的相似程度,由于任意两个不同词的独热向量之间的余弦相似度为 0,所以独热向量不能编码词之间的相似性。另一个原因是随着词汇量的增大,独热向量表示的向量大小也会增大,在词汇量较大的情况下会消耗大量的存储资源与计算资源。

将词转换为词向量时:

首先需要对文本进行分词,再根据需要进行清洗和标准化。
构建词表(Vocabulary),每个词对应一个索引。
使用词嵌入矩阵将词索引转换为词向量。

API使用(这里词嵌入矩阵随机生成,没经过训练)

可使用torch.nn.Embedding来初始化词嵌入矩阵:

python 复制代码
torch.nn.Embedding(num_embeddings, embedding_dim)
# num_embeddings:词的数量
# embedding_dim:词向量的维度

例:

先安装jieba库用于分词:pip install jieba。

python 复制代码
#%%
import torch
import torch.nn as nn
import jieba


# 设置随机种子
torch.manual_seed(42)
text = "自然语言是由文字构成的,而语言的含义是由单词构成的。即单词是含义的最小单位。因此为了让计算机理解自然语言,首先要让它理解单词含义。"
# 自定义停用词和标点符号
stopwords = {"的", "是", "而", "由", ",", "。", "、"}
# 分词,过滤停用词和标点,去重,构建词表
words = [word for word in jieba.lcut(text) if word not in stopwords]
vocab = list(set(words)) # 词表

print(f'去重后的列表f{vocab}')# 去重后的列表f['首先', '语言', '单词', '文字', '即', '因此', '为了', '最小', '计算机', '让', '要', '它', '单位', '理解', '自然语言', '含义', '构成']

# 构建词到索引的映射
word2idx = dict()
for idx, word in enumerate(vocab):
    word2idx[word] = idx
    
print(f'word2idx,根据单词找到下标:{word2idx}')
# 初始化嵌入层
embed = nn.Embedding(num_embeddings=len(word2idx), embedding_dim=5)
# 打印词向量
for idx, word in enumerate(vocab):
    word_vec = embed(torch.tensor(idx)) # 通过索引获取词向量
    print(f"{idx:>2}:{word:8}\t{word_vec.detach().numpy()}")

#打印输出如下
word2idx,根据单词找到下标:{'首先': 0, '语言': 1, '单词': 2, '文字': 3, '即': 4, '因此': 5, '为了': 6, '最小': 7, '计算机': 8, '让': 9, '要': 10, '它': 11, '单位': 12, '理解': 13, '自然语言': 14, '含义': 15, '构成': 16}
 0:首先      	[ 1.9269153  1.4872841  0.9007172 -2.105521   0.6784184]
 1:语言      	[-1.2345449  -0.04306748 -1.604667   -0.7521353   1.648723  ]
 2:单词      	[-0.39247864 -1.4036071  -0.7278813  -0.5594302  -0.7688389 ]
 3:文字      	[ 0.7624454   1.6423169  -0.15959747 -0.49739754  0.43958926]
 4:即       	[-0.75813115  1.0783176   0.80080056  1.6806206   1.2791244 ]
 5:因此      	[ 1.2964228   0.6104665   1.3347378  -0.23162432  0.04175949]
 6:为了      	[-0.2515753   0.8598585  -1.3846737  -0.87123615 -0.22336592]
 7:最小      	[ 1.7173615   0.31888032 -0.42451897  0.30572093 -0.7745925 ]
 8:计算机     	[-1.5575725   0.9956361  -0.87978584 -0.60114205 -1.2741512 ]
 9:让       	[ 2.122785   -1.2346531  -0.48791388 -0.913823   -0.65813726]
10:要       	[ 0.07802387  0.52580875 -0.48799172  1.191369   -0.81400764]
11:它       	[-0.7359928  -1.4032478   0.03600367 -0.06347727  0.6756149 ]
12:单位      	[-0.09780689  1.844594   -1.1845374   1.3835493   1.4451338 ]
13:理解      	[0.85641253 2.2180758  0.5231655  0.34664667 0.5246226 ]
14:自然语言    	[ 1.1412016   0.0516436   0.72810954 -0.7106419  -0.6020683 ]
15:含义      	[ 0.9604488   0.40481427 -0.82776886  1.334703    0.48353928]
16:构成      	[-0.19756168  1.2683114   1.2242628   0.09811721  1.7422527 ]

这段代码是 Python 的 **f-string(格式化字符串)**语法。> 和 : 后面跟的数字是用来控制输出格式的。

具体拆解如下:

1. {idx:>2} 中的 >2

  • >:表示右对齐(Right align)。
  • 2:表示该字段的最小宽度为 2 个字符。
  • 效果: 如果 idx 是 1,输出就是 " 1"(前面补一个空格);如果是 12,输出就是 "12"。这样可以 让输出的序号整齐排列。

2. {word:8} 中的 8

  • 默认行为: 对于字符串,默认是左对齐。
  • 8:表示该字段的最小宽度为 8 个字符。
  • 效果: 如果 word 是 "cat",输出就是 "cat "(后面补 5 个空格);如果单词超过 8 个字符,则原样输出,不会截断。这同样是为了让后面的向量数据对齐,看起来更美观。
相关推荐
Yyyyyy~1 小时前
【深度学习】day2
人工智能·深度学习
梦想不只是梦与想12 小时前
PyTorch、CPU、GPU、CUDA
人工智能·pytorch·python·深度学习·机器学习·cuda
奥惟斯17 小时前
GEO 上线前,先把这 3 类实体信号地基补上
人工智能·深度学习·机器学习·自然语言处理·数据挖掘·数据分析·知识图谱
qq_252941316818 小时前
日本道路病害检测数据集 | 道路病害 裂缝检测 坑洼识别 市政巡检9287期
人工智能·深度学习·yolo·目标检测·计算机视觉·道路检测
Qianxueban18 小时前
如果卷积核大小固定,步长固定,那经过i次卷积,它一个像素的感受野是多大?
人工智能·深度学习·计算机视觉
计算机毕业编程指导师20 小时前
基于深度学习的光伏组件红外图像缺陷识别系统设计与实现
人工智能·python·深度学习·目标检测·毕业设计·课程设计·光伏
牧羊人.3331 天前
卷积神经网络之VGG
人工智能·深度学习·神经网络·算法·cnn
johnsong1 天前
AI前沿日报 | 2026-11-03 — 基因突变:当AI开始重写神经网络
人工智能·深度学习·神经网络
kaixin_啊啊1 天前
【零基础学AI】第 23 章——用神经网络识别图片
人工智能·深度学习·神经网络