ludwig 在命名实体识别中支持特定标签格式的支持

umuewwlo  于 2个月前  发布在  其他
关注(0)|答案(3)|浏览(23)

您的功能请求是否与问题相关?请描述。

我遵循了 tutorial on Named Entity Recognition 。然后我注意到标签格式没有遵循任何最常用的标签格式(standoff,IOB2,BILUO等)。是否可以添加对这些标签格式的支持?

描述使用场景

我尝试用 IOB2 格式训练一个模型替换教程中展示的标签格式(对于我的项目来说太简单和模糊)。例如,我将文本 "Blade Runner is a 1982 neo-noir science fiction film directed by Ridley Scott" 中的标签 Movie Movie O O Date O O O O O O Person Person 替换为 B-Movie I-Movie O O B-Date O O O O O O B-Person I-Person
但是当我用这个训练好的模型预测一些数据点时,我得到了不符合定位规则的标签,例如:
"Harrison Ford and Rutger Hauer starred in it" - I-Person I-Person O B-Person I-Person O O O
可视化 "Harrison Ford" 文本片段的输出,我们可以看到即使前一个标记没有 B-Person 标签,模型仍然错误地给第一个标记("Harrison")分配了 I-Person 标签。而对于 "Rutger Hauer",两个标记的标签都正确地遵循了定位规则。

描述您希望得到的解决方案

期望的解决方案始终是获得标签的正确位置,所以如果我们能输入特定的标签格式(例如 IOB2),模型在发现错误时自动验证标签的位置,并进行必要的替换就很好了。

描述您考虑过的替代方案

我可以自己解决这些错误,但对于一个命名实体识别模型来说,不需要额外的验证就可以自动返回干净的输出是很理想的。

附加上下文

一个实际的例子,展示了模型结果(IOB2)没有遵循其训练时的标签格式:
https://prnt.sc/9SFilgpvlusX

vcudknz3

vcudknz31#

感谢分享这个观点。没有遵循特定格式的原因是为了保持灵活性。例如,可以通过使用0和1来构建一个抽取式摘要模型,或者保留和不作为标签。因此,将格式限制在特定格式上会受到限制。
另一方面,我认为我们可以引入一个后处理函数来捕捉这类情况,一个修复IOB前缀的函数。
如果你有一个已经执行修复的函数,你会考虑贡献它吗?

hzbexzde

hzbexzde2#

嘿,@w4nderlust。当然!我正在使用IOB2标签格式,所以我已经构建了一个函数来修复错误预测的IOB2标签:

from typing import List

def split_to_tags(prediction: str) -> List[str]:
  tags = prediction.split(",")
  return tags

def join_tags(tags: List[str]) -> str:
  prediction = ",".join(tags)
  return prediction

def fix_iob2_tags(tags: List[str]) -> List[str]:
  for i in range(1, len(tags)):
    current_tag = tags[i]
    previous_tag = tags[i-1]

    if current_tag == "<EOS>":  # Check if end of sentence
      break

    if current_tag.startswith("I-"):  # Check if tag starts with 'I-'
      b_tag = f"B-{current_tag[2:]}"
      current_tag = b_tag if previous_tag != b_tag else current_tag

    tags[i] = current_tag
  
  return tags

def postprocessing_ner_tags(prediction_list: List[str], tag_format: str) -> List[str]:

  if tag_format == "iob2":
    fix_func = fix_iob2_tags

  prediction_list_processed = []

  for prediction in prediction_list:
    tags = split_to_tags(prediction)
    tags_fixed = fix_func(tags)
    prediction_fixed = join_tags(tags_fixed)
    prediction_list_processed.append(prediction_fixed)

  return prediction_list_processed

例如,以下代码片段:

prediction_list = ["<SOS>,O,O,I-PER,I-PER,B-MISC,B-PER,B-PER,O,O,<EOS>,I-PER,O,O"]
prediction_list_postprocessed = postprocessing_ner_tags(prediction_list, tag_format="iob2")
print(prediction_list_postprocessed)

输出结果为: ['<SOS>,O,O,B-PER,I-PER,B-MISC,B-PER,B-PER,O,O,<EOS>,I-PER,O,O']

o2rvlv0m

o2rvlv0m3#

你好,@henchaves,你想提交一个修复你提出的PR吗?

相关问题