如何为POS标签生成GloVe嵌入?蟒蛇

时间:2018-04-12 19:44:48

标签: python-3.x machine-learning nlp spacy word-embedding

对于句子分析任务,我想采用与句子相关联的POS标签序列并将其提供给我的模型,就像POS标签是单词一样。

我使用GloVe对句子中的每个单词进行表示,并使用SpaCy生成POS标签。但是,GloVe嵌入对POS标签没有多大意义。所以我将不得不以某种方式为每个POS标签创建嵌入。为POS标签创建嵌入的最佳方法是什么,这样我可以像提供句子一样将POS序列输入我的模型?有人能指出如何用Python中的GloVe做这个代码示例吗?

添加了上下文

我的任务是句子对的二元分类,基于它们的相似性(相似的含义与不同的含义)。

我想使用POS标签作为单词,以便POS标签作为比较句子的额外信息。我当前的模型不使用LSTM作为预测序列的方法。

1 个答案:

答案 0 :(得分:1)

大多数单词嵌入模型仍然依赖于一个基本假设,即单词的含义是由其使用上下文引起的。例如,学习使用skipgram或连续词组表达的word2vec嵌入隐含地假设一个模型,其中单词的表示向量基于与目标单词共同出现的上下文单词,特别是通过学习创建最佳嵌入解决从随机单词对中区分出语境对的词对的分类任务(所谓的负抽样)。

但是如果将输入更改为一系列离散标签(POS标签),则此假设似乎不需要保持准确或合理。词性标签具有指定的含义,其实际上并不是由被其他词性标签包围的上下文引起的,因此用于生成词嵌入的标准学习任务在处理POS标签时不太可能如同它们一样词汇量小得多的词汇。

您的情况下整体句子分析任务是什么?

在问题更新后添加了手头的学习任务。

假设您可以为每个句子示例创建POS输入向量。如果有可能存在N个不同的POS标签,则意味着您的输入将包含来自单词嵌入的一个向量和另一个长度为N的向量,其中组件i中的值表示输入句子中具有POS的术语数标签P_i

例如,让我们假装唯一可能的POS标签是'article','noun'和'verb',并且你有一个带有''article','noun','verb','noun']的句子。然后这会转换为[1, 2, 1],并且您可能希望按句子的长度对其进行标准化。我们将此输入pos1称为句号1,将pos2称为句号2。

让我们将句子1的单词嵌入向量输入称为sentence1sentence1将通过查找来自单独来源的每个单词来计算,例如预训练的word2vec模型或fastText或GloVe,并将它们相加(使用连续的单词包)。 sentence2也一样。

假设您的批量训练数据已经被处理成这些矢量格式,因此给定的单个输入将是4元组的向量:查找句子1的CBOW嵌入向量,对于句子2相同,以及计算的句子1的POS标签的离散表示向量,对于句子2也是如此。

可以使用此数据的模型可能是这样的:

from keras.engine.topology import Input
from keras.layers import Concatenate
from keras.layers.core import Activation, Dense
from keras.models import Model


sentence1 = Input(shape=word_embedding_shape)
sentence2 = Input(shape=word_embedding_shape)
pos1 = Input(shape=pos_vector_shape)
pos2 = Input(shape=pos_vector_shape)

# Note: just choosing 128 as an embedding space dimension or intermediate
# layer size... in your real case, you'd choose these shape params
# based on what you want to model or experiment with. They don't mean
# anything here.

sentence1_branch = Dense(128)(sentence1)
sentence1_branch = Activation('relu')(sentence1_branch)
# ... do whatever other sentence1-only stuff

sentence2_branch = Dense(128)(sentence2)
sentence2_branch = Activation('relu')(sentence2_branch)
# ... do whatever other sentence2-only stuff

pos1_embedding = Dense(128)(pos1)
pos1_branch = Activation('relu')(pos1_embedding)
# ... do whatever other pos1-only stuff

pos2_embedding = Dense(128)(pos2)
pos2_branch = Activation('relu')(pos2_embedding)
# ... do whatever other pos2-only stuff


unified = Concatenate([sentence1_branch, sentence2_branch,
                       pos1_branch, pos2_branch])
# ... do dense layers, whatever, to the concatenated intermediate 
# representations

# finally boil it down to whatever final prediction task you are using, 
# whether it is predicting a sentence similarity score (Dense(1)), 
# or predicting a binary label that indicates whether the sentence 
# pairs are similar or not (Dense(2) then followed by softmax activation, 
# or Dense(1) followed by some type of probability activation like sigmoid).

# Assume your data is binary labeled for similar sentences...
unified = Activation('softmax')(Dense(2)(unified))
unified.compile(loss='binary_crossentropy', other parameters)

# Do training to learn the weights...


# A separate model that will just produce the embedding output
# from a POS input vector, relying on weights learned from the
# training process.
pos_embedding_model = Model(inputs=[pos1], outputs=[pos1_embedding])