python - 推理后如何将标记化的单词转换回原始单词?

标签 python pytorch huggingface-transformers huggingface-tokenizers huggingface-datasets

我正在为已经训练好的 NER 模型编写推理脚本,但是我在将编码的标记(它们的 id)转换为原始单词时遇到了麻烦。

# example input
df = pd.DataFrame({'_id': [1], 'body': ['Amazon and Tesla are currently the best picks out there!']})

# calling method that handles inference:
ner_model = NER()
ner_model.recognize_from_df(df, 'body')

# here is only part of larger NER class that handles the inference:
def recognize_from_df(self, df: pd.DataFrame, input_col: str):
    predictions = []
    df = df[['_id', input_col]].copy()
    dataset = Dataset.from_pandas(df)
    # tokenization, padding, truncation:
    encoded_dataset = dataset.map(lambda examples: self.bert_tokenizer(examples[input_col], 
                                      padding='max_length', truncation=True, max_length=512), batched=True)
    encoded_dataset.set_format(type='torch', columns=['input_ids', 'attention_mask'], device=device)
    dataloader = torch.utils.data.DataLoader(encoded_dataset, batch_size=32)
    encoded_dataset_ids = encoded_dataset['_id']

    for batch in dataloader:
        output = self.model(**batch)
        # decoding predictions and tokens
        for i in range(batch['input_ids'].shape[0]):
            tags = [self.unique_labels[label_id] for label_id in output[i]]
            tokens = [t for t in self.bert_tokenizer.convert_ids_to_tokens(batch['input_ids'][i]) if t != '[PAD]']
        ...
结果接近我需要的:
# tokens:
['[CLS]', 'am', '##az', '##on', 'and', 'te', '##sla', 'are', 'currently', 'the', 'best', 'picks', 'out', 'there', ...]
# tags:
['X', 'B-COMPANY', 'X', 'X', 'O', 'B-COMPANY', 'X', 'O', 'O', 'O', 'O', 'O', 'O', 'O', ...]
如何结合'am', '##az', '##on''B-COMPANY', 'X', 'X'变成一个 token /标签? 我知道有一种方法叫convert_tokens_to_string在 Tokenizer 中,但它只返回一个大字符串,很难映射到标签。
问候

最佳答案

如果您只想“合并”公司名称,那么您可以使用纯 Python 在线性时间内完成此操作。
跳过句子标记[CLS]为简洁起见:

tokens = tokens[1:]
tags = tags[1:]
下面的函数将合并公司 token 并适当增加指针:
def merge_company(tokens, tags):
    generated_tokens = []
    i = 0
    while i < len(tags):
        if tags[i] == "B-COMPANY":
            company_token = [tokens[i]]
            for j in range(i + 1, len(tags)):
                i += 1
                if tags[j] != "X":
                    break
                else:
                    company_token.append(tokens[j][2:])
            generated_tokens.append("".join(company_token))
        else:
            generated_tokens.append(tokens[i])
            i += 1

    return generated_tokens
使用方法很简单,请注意tags需要他们的 X s 也被删除了:
tokens = merge_company(tokens, tags)
tags = [tag for tag in tags if tag != "X"]
这会给你:
['amazon', 'and', 'tesla', 'are', 'currently', 'the', 'best', 'picks', 'out', 'there']
['B-COMPANY', 'O', 'B-COMPANY', 'O', 'O', 'O', 'O', 'O', 'O', 'O']

关于python - 推理后如何将标记化的单词转换回原始单词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69274391/

相关文章:

python - 字符串格式 : Iterate the row values from a csv file

python - 如何要求 STUN 服务器使用 aiortc 生成 ice candidates?

python - Python 的 "best ASCII for this Unicode"数据库在哪里?

python - -bash : !/usr/bin/env: 找不到事件

nlp - 在 Pytorch 中嵌入 3D 数据

nlp - 如何使用 Transformers 库从 XLNet 的输出中获取单词

python - HuggingFace 保存加载模型 (Colab) 进行预测

gpu - 将功能元素逐个应用于Pytorch CUDA张量的并行方式

python-3.x - 这个分配: understanding in-place assignment operations in numpy背后的逻辑是什么