2 回答

TA貢獻1802條經驗 獲得超5個贊
Matcher 并不是真正合適的工具。您應該改為修改標記器。
如果您想保留其他所有內容的處理方式并且只更改連字符的行為,您應該修改現有的中綴模式并保留所有其他設置。當前的英文中綴模式定義在這里:
https://github.com/explosion/spaCy/blob/58533f01bf926546337ad2868abe7fc8f0a3b3ae/spacy/lang/punctuation.py#L37-L49
您可以在不定義自定義分詞器的情況下添加新模式,但如果不定義自定義分詞器,則無法刪除模式。因此,如果您注釋掉連字符模式并定義自定義標記器:
import spacy
from spacy.tokenizer import Tokenizer
from spacy.lang.char_classes import ALPHA, ALPHA_LOWER, ALPHA_UPPER, CONCAT_QUOTES, LIST_ELLIPSES, LIST_ICONS
from spacy.util import compile_infix_regex
def custom_tokenizer(nlp):
infixes = (
LIST_ELLIPSES
+ LIST_ICONS
+ [
r"(?<=[0-9])[+\-\*^](?=[0-9-])",
r"(?<=[{al}{q}])\.(?=[{au}{q}])".format(
al=ALPHA_LOWER, au=ALPHA_UPPER, q=CONCAT_QUOTES
),
r"(?<=[{a}]),(?=[{a}])".format(a=ALPHA),
#r"(?<=[{a}])(?:{h})(?=[{a}])".format(a=ALPHA, h=HYPHENS),
r"(?<=[{a}0-9])[:<>=/](?=[{a}])".format(a=ALPHA),
]
)
infix_re = compile_infix_regex(infixes)
return Tokenizer(nlp.vocab, prefix_search=nlp.tokenizer.prefix_search,
suffix_search=nlp.tokenizer.suffix_search,
infix_finditer=infix_re.finditer,
token_match=nlp.tokenizer.token_match,
rules=nlp.Defaults.tokenizer_exceptions)
nlp = spacy.load("en")
nlp.tokenizer = custom_tokenizer(nlp)
print([t.text for t in nlp("It's 1.50, up-scaled haven't")])
# ['It', "'s", "'", '1.50', "'", ',', 'up-scaled', 'have', "n't"]
在初始化新的 Tokenizer 以保留現有的 tokenizer 行為時,您確實需要提供當前的前綴/后綴/token_match 設置。另請參閱(德語,但非常相似):https ://stackoverflow.com/a/57304882/461847
編輯添加(因為這看起來確實不必要地復雜,你真的應該能夠重新定義中綴模式而無需加載全新的自定義標記器):
如果您剛剛加載了模型(對于 v2.1.8)并且您還沒有調用nlp(),您也可以直接替換infix_re.finditer而不創建自定義標記器:
nlp = spacy.load('en')
nlp.tokenizer.infix_finditer = infix_re.finditer
有一個緩存錯誤應該有望在 v2.2 中得到修復,它可以讓它在任何時候都能正常工作,而不僅僅是新加載的模型。(否則這種行為非常令人困惑,這就是為什么創建自定義標記器對于 v2.1.8 來說是一個更好的通用建議。)
添加回答
舉報