使用spaCy的URL的自定义标记和引理

时间:2018-01-05 10:51:36

标签: python nlp spacy

考虑句子

msg = 'I got this URL https://stackoverflow.com/questions/47637005/handmade-estimator-modifies-parameters-in-init/47637293?noredirect=1#comment82268544_47637293 freed'

接下来,我使用开箱即用的spaCy处理英语的句子:

import spacy
nlp = spacy.load('en')
doc = nlp(msg)

让我们回顾一下[(t, t.lemma_, t.pos_, t.tag_, t.dep_) for t in doc]的输出:

[(I, '-PRON-', 'PRON', 'PRP', 'nsubj'),
 (got, 'get', 'VERB', 'VBD', 'ROOT'),
 (this, 'this', 'DET', 'DT', 'det'),
 (URL, 'url', 'NOUN', 'NN', 'compound'),
 (https://stackoverflow.com/questions/47637005/handmade-estimator-modifies-parameters-in-init/47637293?noredirect=1#comment82268544_47637293,
  'https://stackoverflow.com/questions/47637005/handmade-estimator-modifies-parameters-in-init/47637293?noredirect=1#comment82268544_47637293',
  'NOUN',
  'NN',
  'nsubj'),
 (freed, 'free', 'VERB', 'VBN', 'ccomp')]

我想改进URL片段的处理。特别是,我想:

  1. 将其lemma设置为stackoverflow.com
  2. tag设置为URL
  3. 如何使用spaCy进行操作?我想使用正则表达式(如建议的here)来确定字符串是否是URL并获取域。到目前为止,我没有找到办法。

    编辑我想自定义组件是我需要的。但是,似乎没有办法将基于正则表达式(或任何其他)的可调用放置为patterns

1 个答案:

答案 0 :(得分:5)

自定义网址的正则表达式

您可以使用自定义标记生成器指定URL正则表达式,例如来自https://spacy.io/usage/linguistic-features#native-tokenizers

import regex as re
from spacy.tokenizer import Tokenizer

prefix_re = re.compile(r'''^[\[\("']''')
suffix_re = re.compile(r'''[\]\)"']$''')
infix_re = re.compile(r'''[-~]''')
simple_url_re = re.compile(r'''^https?://''')

def custom_tokenizer(nlp):
    return Tokenizer(nlp.vocab, prefix_search=prefix_re.search,
                                suffix_search=suffix_re.search,
                                infix_finditer=infix_re.finditer,
                                token_match=simple_url_re.match)

nlp = spacy.load('en')
nlp.tokenizer = custom_tokenizer(nlp)

msg = 'I got this URL https://stackoverflow.com/questions/47637005/handmade-estimator-modifies-parameters-in-init/47637293?noredirect=1#comment82268544_47637293 freed'

for i, token in enumerate(nlp(msg)):
    print(i, ':\t', token)

[OUT]:

0 :  I
1 :  got
2 :  this
3 :  URL
4 :  https://stackoverflow.com/questions/47637005/handmade-estimator-modifies-parameters-in-init/47637293?noredirect=1#comment82268544_47637293
5 :  freed

检查令牌是否为URL

您可以检查令牌是否与网址相同,例如

for i, token in enumerate(nlp(msg)):
    print(token.like_url, ':\t', token.lemma_)

[OUT]:

False :  -PRON-
False :  get
False :  this
False :  url
True :   https://stackoverflow.com/questions/47637005/handmade-estimator-modifies-parameters-in-init/47637293?noredirect=1#comment82268544_47637293
False :  free

如果LIKE_URL

更改标记
doc = nlp(msg)

for i, token in enumerate(doc):
    if token.like_url:
        token.tag_ = 'URL'

print([token.tag_ for token in doc])

[OUT]:

['PRP', 'VBD', 'DT', 'NN', 'URL', 'VBN']

用自定义引理替换URL引理

使用正则表达式https://regex101.com/r/KfjQ1G/1

doc = nlp(msg)

for i, token in enumerate(doc):
    if re.match(r'(?:http[s]:\/\/)stackoverflow.com.*', token.lemma_):
        token.lemma_ = 'stackoverflow.com'

print([token.lemma_ for token in doc])

[OUT]:

['-PRON-', 'get', 'this', 'url', 'stackoverflow.com', 'free']