1

有没有一种简单的方法可以告诉“解析器”管道不要更改 的值Token.is_sent_start

所以,故事是这样的:我正在处理预先句子化的文档(1 行 = 1 个句子),我只需要这个分割。我意识到解析器的分段并不总是与我的文档中的相同,所以我不想依赖它所做的分段。

解析器完成后我无法更改分段,所以当它出错时我无法纠正它(你得到一个错误)。如果我自己分割文本然后应用解析器,它会否决我刚刚进行的分割,所以它不起作用。

因此,为了强制保留原始分割并仍然使用预训练的变压器模型(fr_dep_news_trf),我要么:

  1. 禁用解析器,
  2. 将自定义管道添加到 nlp 以设置 Token.is_sent_start 我想要的方式,
  3. 创建文档nlp("an example")

或者,我只是创建一个 Doc

doc = Doc(words=["an", "example"], sent_starts=[True, False])

然后我应用管道的每个元素,除了解析器。

但是,如果我在某些时候仍然需要解析器(我确实需要,因为我需要知道一些子树),如果我只是将它应用于我的 Doc,它会否决已经存在的分段,所以,在某些情况下,分段不正确。所以我做了以下解决方法:

  1. 在列表中保留正确的分段sentences = list(doc.sents)
  2. 在文档上应用解析器
  3. 使用解析器计算的任何语法信息
  4. 从我之前制作的列表中检索我需要的任何句子信息,因为我现在无法信任Token.is_sent_start

它有效,但感觉不太对劲,感觉有点乱。我错过了一种更简单,更清洁的方式吗?

我正在考虑的其他事情是设置自定义扩展,例如,我会使用Token._.is_sent_start而不是 defaultToken.is_sent_start和 custom Doc._.sents,但我担心它可能比有用更令人困惑......

一些用户建议使用span.merge()一个非常相似的主题,但在 spaCy 的最新版本中似乎不存在该功能(防止 spaCy 将段落编号拆分为句子

4

1 回答 1

1

如果提前设置,解析器应该尊重句子边界。有一个突出的错误不会发生这种情况,但这只是在某些标记的句子边界未设置的情况下。

如果您将所有标记边界设置为Trueor False(not None) 然后运行解析器,它会覆盖您的值吗?如果是这样,最好有一个具体的例子,因为这听起来像一个错误。

鉴于此,如果您使用自定义组件在解析器之前设置您的真实句子边界,它应该可以工作。

关于你的其他一些观点......

我认为将句子边界与解析器的边界分开是没有任何意义的——如果你这样做了,你最终可能会得到跨越多个句子的子树,这将是奇怪和无益的。

您在问题中没有提到这一点,但是将每个句子/行视为单独的文档是一种选择吗?(不清楚你是在合并多行并且句子边界是错误的,还是你在单行中传递但它变成了多个句子。)

于 2021-07-29T06:18:59.507 回答