亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

spaCy - 連字符的標記化

spaCy - 連字符的標記化

偶然的你 2022-06-07 19:35:44
美好的一天,我正在嘗試對被標記為單獨標記的連字符進行后處理,因為它們應該是單個標記。例如:Example:Sentence: "up-scaled"Tokens: ['up', '-', 'scaled']Expected: ['up-scaled']現在,我的解決方案是使用匹配器:matcher = Matcher(nlp.vocab)pattern = [{'IS_ALPHA': True, 'IS_SPACE': False},           {'ORTH': '-'},           {'IS_ALPHA': True, 'IS_SPACE': False}]matcher.add('HYPHENATED', None, pattern)def quote_merger(doc):    # this will be called on the Doc object in the pipeline    matched_spans = []    matches = matcher(doc)    for match_id, start, end in matches:        span = doc[start:end]        matched_spans.append(span)    for span in matched_spans:  # merge into one token after collecting all matches        span.merge()    #print(doc)    return docnlp.add_pipe(quote_merger, first=True)  # add it right after the tokenizerdoc = nlp(text)但是,這將導致以下預期問題:Example 2:Sentence: "I know I will be back - I had a very pleasant time"Tokens: ['i', 'know', 'I', 'will', 'be', 'back - I', 'had', 'a', 'very', 'pleasant', 'time']Expected: ['i', 'know', 'I', 'will', 'be', 'back', '-', 'I', 'had', 'a', 'very', 'pleasant', 'time']有沒有一種方法可以只處理由連字符分隔且字符之間沒有空格的單詞?因此,像“up-scaled”這樣的詞將被匹配并組合成一個單獨的標記,而不是“.. back - I ..”非常感謝編輯:我已經嘗試過發布的解決方案:為什么 spaCy 在標記化過程中不會像斯坦福 CoreNLP 那樣保留單詞內連字符?但是,我沒有使用此解決方案,因為它導致帶有撇號 (') 的單詞和帶有小數的數字的錯誤標記化:Sentence: "It's"Tokens: ["I", "t's"]Expected: ["It", "'s"]Sentence: "1.50"Tokens: ["1", ".", "50"]Expected: ["1.50"]這就是為什么我使用 Matcher 而不是嘗試編輯正則表達式的原因。
查看完整描述

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 來說是一個更好的通用建議。)


查看完整回答
反對 回復 2022-06-07
?
料青山看我應如是

TA貢獻1772條經驗 獲得超8個贊

如果nlp = spacy.load('en')拋出錯誤,請使用nlp = spacy.load("en_core_web_sm")



查看完整回答
反對 回復 2022-06-07
  • 2 回答
  • 0 關注
  • 194 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號