如何基于偏移量生成IOB2标签以适配seqeval Hugging Face模型?
基于偏移量生成IOB2标签的实现方案
需求说明
给定包含文本、标注文本、标注偏移量和长度的数据集,需要为每条记录生成对应文本分词后的IOB2标签列表,作为seqeval模型的输入。此前尝试过spaCy实体识别生成IOB标签(无法兼容已有标注)和Pandas处理方案,寻求更优实现。
输入数据示例:
import pandas as pd columns = ['text', 'annotation.text', 'offset', 'length'] lst = [ ['Johnny likes pizza and chocolate, he lives in Italy with Emily.', 'Johnny', 0, 6], ['Johnny likes pizza and chocolate, he lives in Italy with Emily.', 'pizza and chocolate', 13, 19], ['Johnny likes pizza and chocolate, he lives in Italy with Emily.', 'Italy', 46, 5], ['Johnny likes pizza and chocolate, he lives in Italy with Emily.', 'Emily.', 57, 6] ] df = pd.DataFrame(lst, columns=columns)
期望输出需新增IOB_LIST列,每个元素为对应分词的IOB标签列表。
解决方案
核心思路
- 对原始文本进行精准分词,获取每个token的起始/结束偏移量
- 针对每条标注,判断每个token是否落在标注区间
[offset, offset+length)内 - 区间内第一个token标记为
B,后续标记为I,其余标记为O
代码实现
使用spaCy的分词器(仅保留分词功能)来获取准确的token偏移,避免手动计算误差:
import pandas as pd import spacy # 加载spaCy英文分词模型(禁用无关模块,提升效率) nlp = spacy.load("en_core_web_sm", disable=["tagger", "parser", "ner"]) def generate_iob_tags(text, ann_offset, ann_length): # 分词并提取每个token的起始、结束偏移 doc = nlp(text) token_starts = [token.idx for token in doc] token_ends = [token.idx + len(token) for token in doc] iob_tags = [] ann_end = ann_offset + ann_length has_b_tag = False for start, end in zip(token_starts, token_ends): # 判断token与标注区间是否重叠 if start < ann_end and end > ann_offset: if not has_b_tag: iob_tags.append("B") has_b_tag = True else: iob_tags.append("I") else: iob_tags.append("O") return iob_tags # 批量生成IOB标签列 df["IOB_LIST"] = df.apply(lambda row: generate_iob_tags(row["text"], row["offset"], row["length"]), axis=1) # 查看结果 print(df)
方案优势
- 基于spaCy分词器,确保token偏移的准确性,适配含标点、复合词等复杂文本场景
- 完全基于给定的标注偏移量生成标签,兼容已有标注数据,不依赖预训练NER模型
- 函数式实现简洁高效,可直接批量应用于DataFrame
内容的提问来源于stack exchange,提问作者learningtocode
相关产品推荐
相关产品推荐

