有没有一种方法可以获取在BERT中已生成特定令牌的子字符串的位置?

问题描述

我正在为BERT模型(Hugging Face库)提供句子。这些句子通过预训练的分词器分词。我知道您可以使用解码功能将令牌从令牌转换回字符串。

string = tokenizer.decode(...)

但是,重建并不完美。如果使用无大小写的预训练模型,则大写字母会丢失。同样,如果令牌生成器将一个单词拆分为2个令牌,则第二个令牌将以“ ##”开头。例如,“冠状病毒”一词分为两个标记:“冠状病毒”和“ ##病毒”。

所以我的问题是:是否有一种方法可以获取创建每个令牌的子字符串的索引? 例如,使用字符串“东京报告近370例新的冠状病毒病例,创下新的单日记录”。第9个令牌是与“病毒”相对应的令牌。

['[CLS]','tokyo','to','report','nearly','370','new','corona','##virus','cases',','setting','single','-','day','record','[SEP]']

我想告诉我令牌'## virus'来自原始字符串中位于子字符串索引37和41之间的'virus'子字符串。

sentence = "Tokyo to report nearly 370 new coronavirus cases,setting new single-day record"
print(sentence[37:42]) # --> outputs 'virus

解决方法

据我所知,它们不是内置方法,但是您可以自己创建一个方法:

import re
from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

sentence = "Tokyo to report nearly 370 new coronavirus cases,setting new single-day record"

b = []
b.append(([101],))
for m in re.finditer(r'\S+',sentence):
  w = m.group(0)
  t = (tokenizer.encode(w,add_special_tokens=False),(m.start(),m.end()-1))

  b.append(t)

b.append(([102],))

b

输出:

[([101],),([5522],(0,4)),([2000],(6,7)),([3189],(9,14)),([3053],(16,21)),([16444],(23,25)),([2047],(27,29)),([21887,23350],(31,41)),([3572,1010],(43,48)),([4292],(50,56)),(58,60)),([2309,1011,2154],(62,71)),([2501],(73,78)),([102],)]

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...