如何配置SimpleTransformers的BERT自定义NER模型识别多词实体
解决SimpleTransformers BERT NER识别多词实体的配置方法
BERT类NER模型本质是token级识别,但可以通过标注格式规范+模型配置优化+预测后处理实现多词实体的整体识别,具体操作如下:
1. 规范数据集的IOB标注格式
这是核心前提,SimpleTransformers要求NER数据集必须遵循IOB(Inside-Outside-Beginning)标注规则,多词实体的标注要明确区分首尾:
- 多词实体的第一个词标注为
B-place(代表实体起始) - 实体后续的词标注为
I-place(代表实体内部) - 非实体词标注为
O
以你提到的sentence_id=17为例,正确标注格式应该是:
| sentence_id | words | labels |
|---|---|---|
| 17 | united | B-place |
| 17 | states | I-place |
| 17 | south | B-place |
| 17 | Africa | I-place |
| 17 | [其他词] | O |
如果之前所有多词实体都标成B-place,模型无法识别连续的关联token,自然只会输出单个词实体。
2. 训练时调整模型配置
初始化NERModel时,通过参数强化模型对上下文连续token的感知:
from simpletransformers.ner import NERModel, NERArgs model_args = NERArgs() # 调整最大序列长度,确保完整容纳多词实体 model_args.max_seq_length = 128 # 开启滑动窗口,避免长句截断时拆分多词实体 model_args.sliding_window = True # 设置滑动步长,保证多词实体不会被分割到两个窗口 model_args.stride = 0.5 # 初始化模型,指定正确的标签集合 model = NERModel( "bert", "bert-base-uncased", args=model_args, labels=["O", "B-place", "I-place"] )
3. 预测结果的后处理
模型预测输出的是单个token的标签,需要编写后处理代码,把连续的B-place+I-place组合成完整的多词实体:
def merge_multi_word_entities(predictions): merged_results = [] for sent_pred in predictions: current_entity = [] current_type = None for token, label in sent_pred.items(): if label.startswith("B-"): # 先保存上一个未完成的实体 if current_entity: merged_results.append((" ".join(current_entity), current_type)) current_entity = [token] current_type = label.split("-")[1] elif label.startswith("I-") and current_type == label.split("-")[1]: current_entity.append(token) else: # 遇到非实体或不同类型实体,保存当前实体 if current_entity: merged_results.append((" ".join(current_entity), current_type)) current_entity = [] current_type = None # 处理句子末尾的最后一个实体 if current_entity: merged_results.append((" ".join(current_entity), current_type)) return merged_results # 示例使用:预测后合并多词实体 predictions, _ = model.predict(["united states is a country in south Africa"]) final_results = merge_multi_word_entities(predictions) print(final_results) # 输出:[("united states", "place"), ("south Africa", "place")]
4. 可选:更换上下文敏感型预训练模型
如果希望模型本身更擅长捕捉n-gram特征,可以替换为对上下文关联更敏感的预训练模型,比如roberta-base,只需修改初始化时的模型名称即可。
内容的提问来源于stack exchange,提问作者Sweety
相关产品推荐
相关产品推荐

