标记 HTML 文档
Tokenizing an HTML document
我有一个 HTML 文档,我想使用 spaCy 对其进行标记化,同时将 HTML 标签保持为单个标记。
这是我的代码:
import spacy
from spacy.symbols import ORTH
nlp = spacy.load('en', vectors=False, parser=False, entity=False)
nlp.tokenizer.add_special_case(u'<i>', [{ORTH: u'<i>'}])
nlp.tokenizer.add_special_case(u'</i>', [{ORTH: u'</i>'}])
doc = nlp('Hello, <i>world</i> !')
print([e.text for e in doc])
输出为:
['Hello', ',', '<', 'i', '>', 'world</i', '>', '!']
如果我在标签周围放置空格,如下所示:
doc = nlp('Hello, <i> world </i> !')
输出如我所愿:
['Hello', ',', '<i>', 'world', '</i>', '!']
但我想避免对 HTML.
进行复杂的预处理
知道我该如何解决这个问题吗?
您需要创建自定义分词器。
您的自定义 Tokenizer 将与 spaCy 的 tokenizer 完全一样,但它将从前缀和后缀中删除“<”和“>”符号,并且还将添加一个新的前缀和一个新的后缀规则。
代码:
import spacy
from spacy.tokens import Token
Token.set_extension('tag', default=False)
def create_custom_tokenizer(nlp):
from spacy import util
from spacy.tokenizer import Tokenizer
from spacy.lang.tokenizer_exceptions import TOKEN_MATCH
prefixes = nlp.Defaults.prefixes + ('^<i>',)
suffixes = nlp.Defaults.suffixes + ('</i>$',)
# remove the tag symbols from prefixes and suffixes
prefixes = list(prefixes)
prefixes.remove('<')
prefixes = tuple(prefixes)
suffixes = list(suffixes)
suffixes.remove('>')
suffixes = tuple(suffixes)
infixes = nlp.Defaults.infixes
rules = nlp.Defaults.tokenizer_exceptions
token_match = TOKEN_MATCH
prefix_search = (util.compile_prefix_regex(prefixes).search)
suffix_search = (util.compile_suffix_regex(suffixes).search)
infix_finditer = (util.compile_infix_regex(infixes).finditer)
return Tokenizer(nlp.vocab, rules=rules,
prefix_search=prefix_search,
suffix_search=suffix_search,
infix_finditer=infix_finditer,
token_match=token_match)
nlp = spacy.load('en_core_web_sm')
tokenizer = create_custom_tokenizer(nlp)
nlp.tokenizer = tokenizer
doc = nlp('Hello, <i>world</i> !')
print([e.text for e in doc])
郑重声明,这可能变得更容易了:使用当前版本的 Spacy,您不必再创建自定义分词器。足以 1. 扩展中缀(以确保标签与单词分开),以及 2. 添加标签作为特殊情况:
import spacy
from spacy.symbols import ORTH
nlp = spacy.load("en_core_web_trf")
infixes = nlp.Defaults.infixes + [r'(<)']
nlp.tokenizer.infix_finditer = spacy.util.compile_infix_regex(infixes).finditer
nlp.tokenizer.add_special_case(f"<i>", [{ORTH: f"<i>"}])
nlp.tokenizer.add_special_case(f"</i>", [{ORTH: f"</i>"}])
text = """Hello, <i>world</i> !"""
doc = nlp(text)
print([e.text for e in doc])
打印:
['Hello', ',', '<i>', 'world', '</i>', '!']
(这或多或少是 的浓缩版)
我有一个 HTML 文档,我想使用 spaCy 对其进行标记化,同时将 HTML 标签保持为单个标记。 这是我的代码:
import spacy
from spacy.symbols import ORTH
nlp = spacy.load('en', vectors=False, parser=False, entity=False)
nlp.tokenizer.add_special_case(u'<i>', [{ORTH: u'<i>'}])
nlp.tokenizer.add_special_case(u'</i>', [{ORTH: u'</i>'}])
doc = nlp('Hello, <i>world</i> !')
print([e.text for e in doc])
输出为:
['Hello', ',', '<', 'i', '>', 'world</i', '>', '!']
如果我在标签周围放置空格,如下所示:
doc = nlp('Hello, <i> world </i> !')
输出如我所愿:
['Hello', ',', '<i>', 'world', '</i>', '!']
但我想避免对 HTML.
进行复杂的预处理知道我该如何解决这个问题吗?
您需要创建自定义分词器。
您的自定义 Tokenizer 将与 spaCy 的 tokenizer 完全一样,但它将从前缀和后缀中删除“<”和“>”符号,并且还将添加一个新的前缀和一个新的后缀规则。
代码:
import spacy
from spacy.tokens import Token
Token.set_extension('tag', default=False)
def create_custom_tokenizer(nlp):
from spacy import util
from spacy.tokenizer import Tokenizer
from spacy.lang.tokenizer_exceptions import TOKEN_MATCH
prefixes = nlp.Defaults.prefixes + ('^<i>',)
suffixes = nlp.Defaults.suffixes + ('</i>$',)
# remove the tag symbols from prefixes and suffixes
prefixes = list(prefixes)
prefixes.remove('<')
prefixes = tuple(prefixes)
suffixes = list(suffixes)
suffixes.remove('>')
suffixes = tuple(suffixes)
infixes = nlp.Defaults.infixes
rules = nlp.Defaults.tokenizer_exceptions
token_match = TOKEN_MATCH
prefix_search = (util.compile_prefix_regex(prefixes).search)
suffix_search = (util.compile_suffix_regex(suffixes).search)
infix_finditer = (util.compile_infix_regex(infixes).finditer)
return Tokenizer(nlp.vocab, rules=rules,
prefix_search=prefix_search,
suffix_search=suffix_search,
infix_finditer=infix_finditer,
token_match=token_match)
nlp = spacy.load('en_core_web_sm')
tokenizer = create_custom_tokenizer(nlp)
nlp.tokenizer = tokenizer
doc = nlp('Hello, <i>world</i> !')
print([e.text for e in doc])
郑重声明,这可能变得更容易了:使用当前版本的 Spacy,您不必再创建自定义分词器。足以 1. 扩展中缀(以确保标签与单词分开),以及 2. 添加标签作为特殊情况:
import spacy
from spacy.symbols import ORTH
nlp = spacy.load("en_core_web_trf")
infixes = nlp.Defaults.infixes + [r'(<)']
nlp.tokenizer.infix_finditer = spacy.util.compile_infix_regex(infixes).finditer
nlp.tokenizer.add_special_case(f"<i>", [{ORTH: f"<i>"}])
nlp.tokenizer.add_special_case(f"</i>", [{ORTH: f"</i>"}])
text = """Hello, <i>world</i> !"""
doc = nlp(text)
print([e.text for e in doc])
打印:
['Hello', ',', '<i>', 'world', '</i>', '!']
(这或多或少是