【问题标题】:Convert NER SpaCy format to IOB format将 NER SpaCy 格式转换为 IOB 格式
【发布时间】:2020-01-14 09:35:41
【问题描述】:

我有已以 SpaCy 格式标记的数据。例如:

("Who is Shaka Khan?", {"entities": [(7, 17, "PERSON")]}),
("I like London and Berlin.", {"entities": [(7, 13, "LOC"), (18, 24, "LOC")]})

但我想尝试使用任何其他 NER 模型来训练它,例如 BERT-NER,它需要 IOB 标记。 SpaCy数据格式到IOB有转换代码吗?

谢谢!

【问题讨论】:

    标签: nlp spacy named-entity-recognition


    【解决方案1】:

    这与https://stackoverflow.com/a/59209377/461847 密切相关并且大多是从https://stackoverflow.com/a/59209377/461847 复制而来,也请参阅那里的 cmets 中的注释:

    import spacy
    from spacy.gold import biluo_tags_from_offsets
    
    TRAIN_DATA = [
        ("Who is Shaka Khan?", {"entities": [(7, 17, "PERSON")]}),
        ("I like London and Berlin.", {"entities": [(7, 13, "LOC"), (18, 24, "LOC")]}),
    ]
    
    nlp = spacy.load('en_core_web_sm')
    docs = []
    for text, annot in TRAIN_DATA:
        doc = nlp(text)
        tags = biluo_tags_from_offsets(doc, annot['entities'])
        # then convert L->I and U->B to have IOB tags for the tokens in the doc
    

    【讨论】:

      【解决方案2】:

      恐怕您必须编写自己的转换,因为 IOB 编码取决于预训练的表示模型(BERT、RoBERTa 或您选择的任何预训练模型)将使用什么标记化。

      SpaCy 格式指定实体的字符跨度,即

      "Who is Shaka Khan?"[7:17]
      

      将返回"Shaka Khan"。您需要将其与预训练模型使用的标记相匹配。

      以下是使用Huggingface's Transformers 时不同模型如何标记例句的示例。

      • BERT:['Who', 'is', 'S', '##hak', '##a', 'Khan', '?']
      • 罗伯塔:['Who', '_is', '_Sh', 'aka', '_Khan', '?']
      • XLNet:['▁Who', '▁is', '▁Shak', 'a', '▁Khan', '?']

      知道了分词器的工作原理后,您就可以实现转换了。像这样的东西可以用于 BERT 标记化。

      entities = [(7, 17, "PERSON")]}
      tokenized = ['Who', 'is', 'S', '##hak', '##a', 'Khan', '?']
      
      cur_start = 0
      state = "O" # Outside
      tags = []
      for token in tokenized:
          # Deal with BERT's way of encoding spaces
          if token.startswith("##"):
              token = token[2:]
          else:
              token = " " + token
      
          cur_end = cur_start + len(token)
          if state == "O" and cur_start < entities[0][0] < cur_end:
              tags.append("B-" + entitites[0][2])
              state = "I-" + entitites[0][2]
          elif state.startswith("I-") and cur_start < entities[0][1] < cur_end:
              tags.append(state)
              state = "O"
              entities.pop(0)
          else:
              tags.append(state)
          cur_start = cur_end
      

      请注意,如果一个 BERT 令牌包含一个实体的结尾和下一个实体的开头,则 sn-p 会中断。分词器也不区分原始字符串中有多少个空格(或其他空格),这也是潜在的错误来源。

      【讨论】:

        【解决方案3】:

        首先,您需要将带注释的json 文件转换为csv
        然后你可以运行下面的代码转换成spaCy V2 Binary格式

        df = pd.read_csv('SC_CSV.csv')
        l1 = []
        l2 = []
        
        for i in range(0, len(df['ner'])):
            l1.append(df['ner'][i])
            l2.append({"entities":[(0,len(df['ner'][i]),df['label'][i])]})
            
        TRAIN_DATA = list(zip(l1, l2))
        TRAIN_DATA 
        

        现在是spaCy V2 格式的TRAIN_DATA

        这有助于将文件从 Spacy v2 格式转换为全新的 Spacy v3 格式。

        import pandas as pd
        from tqdm import tqdm
        import spacy
        from spacy.tokens import DocBin
        
        nlp = spacy.blank("en") # load a new spacy model
        db = DocBin() # create a DocBin object
        
        for text, annot in tqdm(TRAIN_DATA): # data in previous format
            doc = nlp.make_doc(text) # create doc object from text
            ents = []
            for start, end, label in annot["entities"]: # add character indexes
                span = doc.char_span(start, end, label=label, alignment_mode="contract")
                if span is None:
                    print("Skipping entity")
                else:
                    ents.append(span)
            doc.ents = ents # label the text with the ents
            db.add(doc)
        
        db.to_disk("./train.spacy") # save the docbin object
        

        【讨论】:

          猜你喜欢
          • 2022-01-02
          • 1970-01-01
          • 2021-03-13
          • 1970-01-01
          • 2021-07-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-02
          相关资源
          最近更新 更多