python - 如何将自定义规则添加到 spaCy 标记器以将 HTML 分解为单个标记?
问题描述
我知道有很多资源可以解决这个问题,但我无法让 spaCy 完全按照我的意愿去做。
我想向我的 spaCy 标记器添加规则,以便我的文本中的 HTML 标记(例如<br/>
等)成为单个标记。
我现在正在使用“merge_noun_chunks”管道,所以我得到了这样的令牌:(
"documentation<br/>The Observatory Safety System"
这是一个单一的令牌)
我想添加一条规则,以便将其拆分为 3 个标记:
"documentation", "<br/>", "The Observatory Safety System"
我查找了很多资源:这里,也在这里。但我无法让它在我的情况下工作
我试过这个:
infix_re = re.compile(r'''<[\w+]\/>''')
prefix_re = compile_prefix_regex(nlp.Defaults.prefixes)
suffix_re = compile_suffix_regex(nlp.Defaults.suffixes)
return Tokenizer(nlp.vocab, prefix_search=prefix_re.search,
suffix_search=suffix_re.search,
infix_finditer=infix_re.finditer,
token_match=None)
我不确定我是否完全理解更改中缀的作用。我还应该按照这里的建议<
从前缀中删除吗?
解决方案
实现这一点的一种方法似乎涉及使标记器
- 分解包含没有空格的标记的标记,以及
- “块”标签状序列作为单个标记。
要拆分示例中的标记,您可以修改标记器中缀(以此处描述的方式):
infixes = nlp.Defaults.infixes + [r'([><])']
nlp.tokenizer.infix_finditer = spacy.util.compile_infix_regex(infixes).finditer
为确保标签被视为单个标记,您可以使用“特殊情况”(请参阅标记器概述或方法文档)。您将为打开、关闭和空标签添加特殊情况,例如:
# open and close
for tagName in "html body i br p".split():
nlp.tokenizer.add_special_case(f"<{tagName}>", [{ORTH: f"<{tagName}>"}])
nlp.tokenizer.add_special_case(f"</{tagName}>", [{ORTH: f"</{tagName}>"}])
# empty
for tagName in "br p".split():
nlp.tokenizer.add_special_case(f"<{tagName}/>", [{ORTH: f"<{tagName}/>"}])
综合起来:
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
for tagName in "html body i br p".split():
nlp.tokenizer.add_special_case(f"<{tagName}>", [{ORTH: f"<{tagName}>"}])
nlp.tokenizer.add_special_case(f"</{tagName}>", [{ORTH: f"</{tagName}>"}])
for tagName in "br p".split():
nlp.tokenizer.add_special_case(f"<{tagName}/>", [{ORTH: f"<{tagName}/>"}])
这似乎产生了预期的结果。例如,申请...
text = """<body>documentation<br/>The Observatory <p> Safety </p> System</body>"""
print("Tokenized:")
for t in nlp(text):
print(t)
... 将完整且独立地打印标签:
# ... snip
documentation
<br/>
The
# ... snip
我发现标记器的解释方法在这种情况下非常有用。它为您提供了标记化原因的细分。
推荐阅读
- f# - 是否可以将 F# 类型提供程序设计为生成 AST 类型和解析器?
- angular - 当我尝试安装 Angular 时权限被拒绝
- javascript - 每天定时运行 JavaScript 函数
- android - 如何在 Kotlin 中处理 GSON 的 null 案例?
- mysql - 将 Cpanel 数据库与 AWS RDS 同步
- typescript - 如何要求一些属性但允许更多?
- c - Using Shell Script to Send Data to Running Process
- pycharm - Delete all lines that have a specific word in Pycharm
- flutter - Firebase 数据库颤动
- python - how to find the time in effective way when value get cross the threshold limit