如何使用复杂的 token_match 自定义分词器?
How to customize tokenizer with complex token_match?
我正在使用 spacy
来做一些定制的分词器。我想将 API 名称作为一个 token
。如srcs[offset].remaining()
句中:
Up to the first srcs[offset].remaining() bytes of this sequence are written from buffer srcs[offset].
我已将 token_match 添加到 tokenizer,但它已被后缀覆盖。
代码如下:
import re
import spacy
from spacy.tokenizer import Tokenizer
def customize_tokenizer_api_name_recognition(nlp):
# add api_name regex, such aaa.bbb(cccc) or aaa[bbb].ccc(ddd)
api_name_match = re.compile("(\w+(\[[\w+-]+\])?\.)+\w+\(.*?\)", re.UNICODE).match
nlp.tokenizer.token_match = api_name_match
if __name__ == '__main__':
nlp = spacy.load('en_core_web_sm')
customize_tokenizer_api_name_recognition(nlp)
sentence = "Up to the first srcs[offset].remaining() bytes of this sequence are written from buffer srcs[offset]."
doc = nlp(sentence)
print([token.text for token in doc])
# output: ['Up', 'to', 'the', 'first', 'srcs[offset].remaining', '(', ')', 'bytes', 'of', 'this', 'sequence', 'are', 'written', 'from', 'buffer', 'srcs[offset', ']', '.']
# expected output: ['Up', 'to', 'the', 'first', 'srcs[offset].remaining()', 'bytes', 'of', 'this', 'sequence', 'are', 'written', 'from', 'buffer', 'srcs[offset', ']', '.']
我看到了一些相关问题#4573, #4645 and the doc。然而所有的例子都是简单的正则表达式,他们通过删除一些 prefixes_search 来解决。复杂的正则表达式呢?如何解决这类问题?
ps:我以前是用doc.retokenize()
来实现的。能否通过自定义tokenizer更优雅的解决问题?
环境
- 操作系统:Win 10
- Python 使用的版本:python 3.7.3
- spaCy 使用的版本:spacy 2.2.3
tokenizer 解决方案与#4573 相同,只是您自定义了后缀。不过,这不是一个很好的解决方案,因为 )
在任何地方都不是后缀。
我认为 doc.retokenize()
的解决方案更适合 v2.2。您可以在添加到管道开头的小型自定义管道组件中执行此操作。
(有两个 token_match
选项可能更好,一个有前缀和后缀,一个没有,但让分词器选项比现在更复杂也不是很好。)
我正在使用 spacy
来做一些定制的分词器。我想将 API 名称作为一个 token
。如srcs[offset].remaining()
句中:
Up to the first srcs[offset].remaining() bytes of this sequence are written from buffer srcs[offset].
我已将 token_match 添加到 tokenizer,但它已被后缀覆盖。
代码如下:
import re
import spacy
from spacy.tokenizer import Tokenizer
def customize_tokenizer_api_name_recognition(nlp):
# add api_name regex, such aaa.bbb(cccc) or aaa[bbb].ccc(ddd)
api_name_match = re.compile("(\w+(\[[\w+-]+\])?\.)+\w+\(.*?\)", re.UNICODE).match
nlp.tokenizer.token_match = api_name_match
if __name__ == '__main__':
nlp = spacy.load('en_core_web_sm')
customize_tokenizer_api_name_recognition(nlp)
sentence = "Up to the first srcs[offset].remaining() bytes of this sequence are written from buffer srcs[offset]."
doc = nlp(sentence)
print([token.text for token in doc])
# output: ['Up', 'to', 'the', 'first', 'srcs[offset].remaining', '(', ')', 'bytes', 'of', 'this', 'sequence', 'are', 'written', 'from', 'buffer', 'srcs[offset', ']', '.']
# expected output: ['Up', 'to', 'the', 'first', 'srcs[offset].remaining()', 'bytes', 'of', 'this', 'sequence', 'are', 'written', 'from', 'buffer', 'srcs[offset', ']', '.']
我看到了一些相关问题#4573, #4645 and the doc。然而所有的例子都是简单的正则表达式,他们通过删除一些 prefixes_search 来解决。复杂的正则表达式呢?如何解决这类问题?
ps:我以前是用doc.retokenize()
来实现的。能否通过自定义tokenizer更优雅的解决问题?
环境
- 操作系统:Win 10
- Python 使用的版本:python 3.7.3
- spaCy 使用的版本:spacy 2.2.3
tokenizer 解决方案与#4573 相同,只是您自定义了后缀。不过,这不是一个很好的解决方案,因为 )
在任何地方都不是后缀。
我认为 doc.retokenize()
的解决方案更适合 v2.2。您可以在添加到管道开头的小型自定义管道组件中执行此操作。
(有两个 token_match
选项可能更好,一个有前缀和后缀,一个没有,但让分词器选项比现在更复杂也不是很好。)