# question-classification-with-multi-level-attention-mechanism-and-keras
question classification with multi-level attention mechanism 使用多层级注意力机制和keras实现问题分类
# 1 准备工作
## 1.1 什么是词向量?
”词向量”(词嵌入)是将一类将词的语义映射到向量空间中去的自然语言处理技术。即将一个词用特定的向量来表示,向量之间的距离(例如,任意两个向量之间的L2范式距离或更常用的余弦距离)一定程度上表征了的词之间的语义关系。由这些向量形成的几何空间被称为一个嵌入空间。
传统的独热表示( one-hot representation)仅仅将词符号化,不包含任何语义信息。必须考虑将语义融入到词表示中。
解决办法将原来稀疏的巨大维度压缩嵌入到一个更小维度的空间进行分布式表示。
例如,“椰子”和“北极熊”是语义上完全不同的词,所以它们的词向量在一个合理的嵌入空间的距离将会非常遥远。但“厨房”和“晚餐”是相关的话,所以它们的词向量之间的距离会相对小。
理想的情况下,在一个良好的嵌入空间里,从“厨房”向量到“晚餐”向量的“路径”向量会精确地捕捉这两个概念之间的语义关系。在这种情况下,“路径”向量表示的是“发生的地点”,所以你会期望“厨房”向量 - “晚餐"向量(两个词向量的差异)捕捉到“发生的地点”这样的语义关系。基本上,我们应该有向量等式:晚餐 + 发生的地点 = 厨房(至少接近)。如果真的是这样的话,那么我们可以使用这样的关系向量来回答某些问题。例如,应用这种语义关系到一个新的向量,比如“工作”,我们应该得到一个有意义的等式,工作+ 发生的地点 = 办公室,来回答“工作发生在哪里?”。
词向量通过降维技术表征文本数据集中的词的共现信息。方法包括神经网络(“Word2vec”技术),或矩阵分解。
## 1.2 获取词向量
词向量 对与中文自然语言处理任务 是基石,一般情况下 有两种获取方式:
- 别人训练好的百科数据。优势:包含词语多,符合日常用语的语义;劣势:专有名词不足,占用空间大;
- 自己训练。优势:专有名词,针对具体任务语义更准确; 劣势:泛化性差。
步骤:
```
graph LR
文本-->分词
分词-->训练词向量
训练词向量-->保存词向量
```
具体代码:
```python
import gensim
## 训练自己的词向量,并保存。
def trainWord2Vec(filePath):
sentences = gensim.models.word2vec.LineSentence(filePath) # 读取分词后的 文本
model = gensim.models.Word2Vec(sentences, size=100, window=5, min_count=1, workers=4) # 训练模型
model.save('./CarComment_vord2vec_100')
def testMyWord2Vec():
# 读取自己的词向量,并简单测试一下 效果。
inp = './CarComment_vord2vec_100' # 读取词向量
model = gensim.models.Word2Vec.load(inp)
print('空间的词向量(100维):',model['空间'])
print('打印与空间最相近的5个词语:',model.most_similar('空间', topn=5))
if __name__ == '__main__':
#trainWord2Vec('./CarCommentAll_cut.csv')
testMyWord2Vec()
pass
```
这样我们就 拥有了 预训练的 词向量文件`CarComment_vord2vec_100` 。
下一单元 继续讲解如何在keras中使用它。
# 2 转化词向量为keras所需格式
上一步拿到了所有词语的词向量,但还需转化词向量为keras所需格式。众所周知,keras中使用预训练的词向量的层是`Embedding层`,而`Embedding层`中所需要的格式为 一个巨大的“矩阵”:第i列表示词索引为i的词的词向量
所以,本单元的总体思路就是给 Embedding 层提供一个 `[ word : word_vector]` 的词典来初始化`Embedding层`中所需要的大矩阵 ,并且标记为不可训练。
## 2.1 获取所有词语word和词向量
首先要导入 预训练的词向量。
```python
## 1 导入 预训练的词向量
myPath = './CarComment_vord2vec_100' # 本地词向量的地址
Word2VecModel = gensim.models.Word2Vec.load(myPath) # 读取词向量
vector = Word2VecModel.wv['空间'] # 词语的向量,是numpy格式
```
`gensim`的`word2vec`模型 把所有的单词和 词向量 都存储在了`Word2VecModel.wv`里面,讲道理直接使用这个`.wv`即可。 但是我们打印这个东西的 类型
```python
print(type(Word2VecModel.wv)) # 结果为:Word2VecKeyedVectors
for i,j in Word2VecModel.wv.vocab.items():
print(i) # 此时 i 代表每个单词
print(j) # j 代表封装了 词频 等信息的 gensim“Vocab”对象,例子:Vocab(count:1481, index:38, sample_int:3701260191)
break
```
发现它是 gensim自己封装的一种数据类型:`Word2VecKeyedVectors`,
```
<class 'gensim.models.keyedvectors.Word2VecKeyedVectors'>
```
不能使用`for循环`迭代取单词。
## 2.2 构造“词语-词向量”字典
第二步 构造数据:
- 构造 一个list存储所有单词:vocab_list 存储所有词语。
- 构造一个字典word_index :`{word : index}` ,key是每个词语,value是单词在字典中的序号。 在后期 tokenize(序号化) 训练集的时候就是用该词典。
构造包含
- 构造一个 大向量矩阵embeddings_matrix (按照embedding层的要求):行数 为 所有单词数,比如 10000;列数为 词向量维度,比如100。
代码:
```python
## 2 构造包含所有词语的 list,以及初始化 “词语-序号”字典 和 “词向量”矩阵
vocab_list = [word for word, Vocab in Word2VecModel.wv.vocab.items()]# 存储 所有的 词语
word_index = {" ": 0}# 初始化 `[word : token]` ,后期 tokenize 语料库就是用该词典。
word_vector = {} # 初始化`[word : vector]`字典
# 初始化存储所有向量的大矩阵,留意其中多一位(首行),词向量全为 0,用于 padding补零。
# 行数 为 所有单词数+1 比如 10000+1 ; 列数为 词向量“维度”比如100。
embeddings_matrix = np.zeros((len(vocab_list) + 1, Word2VecModel.vector_size))
```
## 2.3 填充字典和矩阵
第三步:填充 上述步骤中 的字典 和 大矩阵
```python
## 3 填充 上述 的字典 和 大矩阵
for i in range(len(vocab_list)):
# print(i)
word = vocab_list[i] # 每个词语
word_index[word] = i + 1 # 词语:序号
word_vector[word] = Word2VecModel.wv[word] # 词语:词向量
embeddings_matrix[i + 1] = Word2VecModel.wv[word] # 词向量矩阵
```
## 2.4 在 keras的Embedding层中使用 预训练词向量
```python
from keras.layers import Embedding
EMBEDDING_DIM = 100 #词向量维度
embedding_layer = Embedding(input_dim = len(embeddings_matrix), # 字典长度
EMBEDDING_DIM, # 词向量 长度(100)
weights=[embeddings_matrix], # 重点:预训练的词向量系数
input_length=MAX_SEQUENCE_LENGTH, # 每句话的 最大长度(必须padding)
trainable=False # 是否在 训练的过程中 更新词向量
)
```
- Embedding层的输入shape
此时 输入Embedding层的数据的维度是
形如`(samples,sequence_length)`的2D张量,注意,此时句子中的词语word已经被转化为 index(依靠`word_index`,所以在 `embedding层`之前 往往结合 `input层`, 用于将 文本 分词 转化为数字形式)
- Embedding层的输出shape
Embedding层把 所有输入的序列中的整数,替换为对应的词向量矩阵中对应的向量(也就是它的词向量),比如一句话[1,2,8]将被序列[词向量第[1]行,词向量第[2]行,词向量第[8]行]代替。
这样,输入一个2D张量后,我们可以得到一个3D张量:`(samples, s
MarcoPage
- 粉丝: 4420
- 资源: 8836
最新资源
- 硅酸钠块行业分析:2023年全球市场规模大约为349百万美元.docx
- 光学扩散膜行业分析:2023年全球市场规模大约为352百万美元.docx
- 合成生物学技术行业分析:全球收入达到1279.6百万美元.docx
- 海上能源无人潜水器市场分析:2023年全球市场规模为854百万美元.docx
- 呼气分子诊断行业分析:2023年全球市场规模大约为234百万美元.docx
- 环氧豆油丙烯酸酯行业分析:2023年全球市场规模大约为871百万美元.docx
- 滑雪头盔式耳机行业分析:2023年全球市场规模大约为51.5百万美元.docx
- 幻想(虚拟)体育行业分析:北美和欧洲占全球约70%的市场份额.docx
- 会话营销软件行业分析:全球收入约为564.9百万美元.docx
- 火灾警报设备行业分析:全球市场收入约为19130百万美元.docx
- 基础unity,控制物体的简单移动,值得学习一下
- 活动行业分析:全球收入约为342100百万美元.docx
- 机械键盘行业分析:2023年全球市场规模大约为1245百万美元.docx
- 即时物流行业分析:2023年全球市场规模大约为23770百万美元.docx
- 奖励管理软件行业研究:全球收入约为692.5百万美元.docx
- 洁净室环境在线监测软件行业分析:北美占有约25%的全球市场份额.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈