为 OOV 词添加新向量的正确方法

Proper way to add new vectors for OOV words

我使用的是一些特定领域的语言,其中有很多 OOV 词以及一些拼写错误。我注意到 Spacy 只会为这些 OOV 词分配一个全零向量,所以我想知道处理这个问题的正确方法是什么。如果可能的话,我感谢对所有这些要点的澄清:

  1. pre-train命令具体是做什么的?老实说,我似乎无法正确解析网站上的解释:

Pre-train the “token to vector” (tok2vec) layer of pipeline components, using an approximate language-modeling objective. Specifically, we load pretrained vectors, and train a component like a CNN, BiLSTM, etc to predict vectors which match the pretrained ones

生成向量的部分不是tok2vec吗?那么这个命令不应该改变产生的向量吗? 加载预训练向量然后训练一个组件来预测这些向量是什么意思?这样做的目的是什么?

--use-vectors 标志有什么作用? --init-tok2vec 标志有什么作用?这是否包含在文档中?

  1. 看来 pretrain 不是我要找的,它不会改变给定单词的向量。生成包含我的 OOV 单词但仍包含该语言的一般知识的一组新向量的最简单方法是什么?

  2. 据我所知,Spacy 的预训练模型使用的是快速文本向量。 Fasttext 网站提到:

A nice feature is that you can also query for words that did not appear in your data! Indeed words are represented by the sum of its substrings. As long as the unknown word is made of known substrings, there is a representation of it!

不过Spacy好像没有使用这个功能。有没有办法仍然将其用于 OOV 词?

非常感谢

我认为不同的组件存在一些混淆 - 我会尝试澄清:

  1. 分词器不生成向量。它只是一个组件 将文本分割成标记。在 spaCy 中,它是 rule-based 而不是 可训练的,与向量没有任何关系。它看着 空格和标点符号以确定哪些是句子中的唯一标记。
  2. spaCy 中的 nlp 模型可以具有可在 Token 级别访问的预定义​​(静态)词向量。每个令牌都相同 Lexeme 得到相同的向量。有些 tokens/lexemes 可能确实是 OOV,像拼写错误。如果你想 redefine/extend 所有向量 在模型中使用,您可以使用类似 init-model(spaCy v3 中的init vectors)的东西。
  3. tok2vec 层是一个机器学习组件,它学习如何为令牌生成合适的(动态)向量。它通过查看来做到这一点 at 标记的词法属性,但也可能包括静态 令牌的向量(参见第 2 项)。该组件通常不单独使用,而是作为另一个组件的一部分,例如 NER。它将是 NER 模型的第一层,它可以作为 NER 训练的一部分进行训练,以生成适合您的 NER 任务的向量。

在 spaCy v2 中,您可以先使用 pretrain 训练一个 tok2vec 组件,然后将此组件用于后续的 train 命令。请注意,两个命令中的所有设置都必须相同,以使图层兼容。

回答您的问题:

Isn't the tok2vec the part that generates the vectors?

如果你指的是静态向量,那就不是。 tok2vec 组件在静态向量之上生成新向量(可能具有不同的维度),但它不会更改静态向量。

What does it mean loading pretrained vectors and then train a component to predict these vectors? What's the purpose of doing this?

目的是获得一个 tok2vec 已经从外部矢量数据预训练的组件。外部向量数据已经嵌入了标记的某些“含义”或“相似性”,可以说,这被转移到 tok2vec 组件中,该组件学习产生相同的相似性。关键是这个新的 tok2vec 组件可以在随后的 train 命令中进一步使用 fine-tuned (参见第 3 项)

Is there a way to still make use of this for OOV words?

这真的取决于你的“用途”是什么。至于如何定义 mentions, you can set the vectors yourself, or you can implement a user hook which will decidetoken.vector.

希望对您有所帮助。如果不了解您为什么需要 OOV 向量/您的 use-case 是什么,我真的无法推荐您遵循的最佳方法。很高兴在评论中进一步讨论!