词汇表征
计算机是无法直接认识单词的,所以为了让计算机能更好地理解人类语言,需要将词汇进行表征。之前用到的方法是One-hot表征,即创建一个向量,将对应单词的位置用1表示,其余位置用0表示。这种方法的缺点是无法获得词与词之间的相关性。另一种方法是特征表征,即词嵌入,用不同的特征对单词进行特征化表示。
词嵌入能够帮助实现类比推理。通过不同词向量之间的相减计算,可以发现不同词之间的类比关系,如“man—woman”以及“king—queen”。计算相似度可采用余弦相似度函数以及欧氏距离。
以下为代码示例,通过word_a和word_b一组词类别word_c和目标词:
def complete_analogy(word_a, word_b, word_c, word_to_vec_map):
# 转小写
word_a, word_b, word_c = word_a.lower(), word_b.lower(), word_c.lower()
# 获取三个单词的词嵌入
e_a, e_b, e_c = word_to_vec_map[word_a], word_to_vec_map[word_b], word_to_vec_map[word_c]
words = word_to_vec_map.keys()
# 初始化
max_cosine_sim = -100
best_word = None
# 遍历词向量集
for w in words:
# 避免最佳单词成为输入的三个单词之一
if w in [word_a, word_b, word_c] :
continue
# 计算余弦相似度
cosine_sim = cosine_similarity(e_b - e_a, word_to_vec_map[w] - e_c)
# 选择余弦相似度最大值和最佳单词
if cosine_sim > max_cosine_sim:
max_cosine_sim = cosine_sim
best_word = w
return best_word
学习算法
一个词汇表对应一个嵌入矩阵,学习好了嵌入矩阵后,通过嵌入矩阵与对应词的One-hot向量相乘,即可得到该词汇的Embedding。词嵌入的学习算法有Word2Vec和GloVe。
在Skip-grams模型中,我们需要抽取上下文(Content)和目标词(Target)配对,来构造一个监督学习问题。缺点是Softmax层计算的时间复杂度较高。
上下文不一定是要目标词前面或者后面离得最近的几个单词,而是随机选择一个词作为上下文,同时在上下文的一定距离范围内随机选择另外一个词作为目标词。构造这样一个监督学习问题的目的,并不是想要解决监督学习问题本身,而是想要使用这个问题来学习一个好的词嵌入模型。
负采样
Word2Vec可以使用负采样方法提高效率。定义一个新的学习问题:预测两个词之间是否是上下文-目标词对,如果是词对,则学习的目标为1,否则为0。下一步使用k次相同的上下文,随机选择不同的目标词,并对相应的词对进行正负样本的标记,生成训练集。最后学习x—y的映射关系。
GloVe词向量
GloVe(global vectors for word representation)词向量模型是另一种计算词嵌入的方法。本模型中,要定义一个量$X_{ij}$,表示目标词i出现在上下文j的次数。
情感分类
情感分类是通过一段文本判断其内容的情感趋向,是自然语言处理最重要的模块之一。RNN模型配合词嵌入是一个很好的解决方案,首先获取一个训练好的词嵌入矩阵E,得到每个词的词嵌入向量,输入到many-to-one的RNN模型中,最后通过softmax分类器,得到最后的输出。
消除偏见
学习词嵌入向量后,可能会出现性别、种族等偏见。定义偏见的方向后,对相应的词汇相减并求平均,可以使用中和化、均衡等方法消除偏见。
def Emojify_V2(input_shape, word_to_vec_map, word_to_index):
# 定义sentence_indices作为模型输入
sentence_indices = Input(shape=input_shape,dtype='int32')
# 创建使用GloVe向量预训练的嵌入层
embedding_layer = pretrained_embedding_layer(word_to_vec_map, word_to_index)
# 通过嵌入层传播sentence_indices,获得embeddings
embeddings = embedding_layer(sentence_indices)
# 通过具有128维隐藏状态的LSTM层传播embeddings,返回输出序列
X = LSTM (128, return_sequences=True)(embeddings)
# 添加Dropout,防止过拟合
X = Dropout(0.5)(X)
# 通过LSTM层传播,这里返回单一隐藏状态,而不是上一次的序列
X = LSTM (128, return_sequences=False)(X)
# 添加Dropout
X = Dropout(0.5)(X)
# 通过全连接层传播
X = Dense(5)(X)
# Softmax激活
X = Activation('softmax')(X)
# 创建sentence_indices->x的模型
model = Model(sentence_indices, X)
return model