Jay*_*Jay 6 python tokenize bert-language-model huggingface-transformers huggingface-tokenizers
我有一个句子,我需要返回特定单词左右两侧 N 个 BERT 标记对应的文本。
from transformers import BertTokenizer
tz = BertTokenizer.from_pretrained("bert-base-cased")
sentence = "The Natural Science Museum of Madrid shows the RECONSTRUCTION of a dinosaur"
tokens = tz.tokenize(sentence)
print(tokens)
>>['The', 'Natural', 'Science', 'Museum', 'of', 'Madrid', 'shows', 'the', 'R', '##EC', '##ON', '##ST', '##R', '##UC', '##TI', '##ON', 'of', 'a', 'dinosaur']
Run Code Online (Sandbox Code Playgroud)
我想要的是获取与令牌马德里左侧和右侧的4个令牌相对应的文本。所以我想要标记: ['Natural', 'Science', 'Museum', 'of', 'Madrid', 'shows', 'the', 'R', '##EC'] 然后将它们转换为原文。在本例中,它将是“马德里自然科学博物馆展示 REC”。
有没有办法做到这一点?
cro*_*oik 11
除了Jindrich提供的有关信息丢失的信息之外,我想补充一点,huggingface 提供了一个内置方法来将令牌转换为字符串(丢失的信息仍然丢失!)。该方法称为convert_tokens_to_string:
tz.convert_tokens_to_string(tokens[1:10])
Run Code Online (Sandbox Code Playgroud)
输出:
'Natural Science Museum of Madrid shows the REC'
Run Code Online (Sandbox Code Playgroud)
不幸的是,BERT 使用的单词片段标记化并不是无损的,即,永远不能保证在去标记化后得到相同的句子。这与使用完全可恢复的 SentencePiece 的 RoBERTa 有很大区别。
您可以获得所谓的预标记化文本,其中合并以 开头的标记##。
pretok_sent = ""
for tok in tokens:
if tok.startswith("##"):
pretok_sent += tok[2:]
else:
pretok_sent += " " + tok
pretok_sent = pretok_sent[1:]
Run Code Online (Sandbox Code Playgroud)
此代码片段重建了示例中的句子,但请注意,如果句子包含标点符号,则标点符号将与其他标记保持分离,这就是预标记化。该句子可以如下所示:
'This is a sentence ( with brackets ) .'
Run Code Online (Sandbox Code Playgroud)
从预标记化到标准句子是有损步骤(您永远无法知道原始句子中是否存在以及有多少额外空格)。您可以通过应用去标记化规则来获得标准句子,例如在sacremoses中。
import sacremoses
detok = sacremoses.MosesDetokenizer('en')
detok(sent.split(" "))
Run Code Online (Sandbox Code Playgroud)
这导致:
'This is a sentence (with brackets).'
Run Code Online (Sandbox Code Playgroud)