【问题标题】:How to change from CoNLL format into a sentences list?如何从 CoNLL 格式更改为句子列表?
【发布时间】:2021-04-07 10:47:41
【问题描述】:

我有一个理论上是 CoNLL 格式的 txt 文件。像这样:

a O
nivel B-INDC
de O
la O
columna B-ANAT
anterior I-ANAT
del I-ANAT
acetabulo I-ANAT


existiendo O
minimos B-INDC
cambios B-INDC
edematosos B-DISO
en O
la O
medular B-ANAT
(...)

我需要将其转换为句子列表,但我没有找到方法。我尝试使用 conllu 库的解析器:

from conllu import parse
sentences = parse("location/train_data.txt")

但他们给出了错误:ParseException: Invalid line format, line must contain either tabs or two spaces.

我怎样才能得到这个?

["a nivel de la columna anterior del acetabulo", "existiendo minimos cambios edematosos en la medular", ...]

谢谢

【问题讨论】:

    标签: python nlp format conll


    【解决方案1】:

    对于 NLP 问题,第一个起点是 Huggingface - 对我来说总是 - :D 你的问题有一个很好的例子:https://huggingface.co/transformers/custom_datasets.html

    在这里,他们展示了一个完全符合您要求的功能:

    from pathlib import Path
    import re
    
    def read_wnut(file_path):
        file_path = Path(file_path)
    
        raw_text = file_path.read_text().strip()
        raw_docs = re.split(r'\n\t?\n', raw_text)
        token_docs = []
        tag_docs = []
        for doc in raw_docs:
            tokens = []
            tags = []
            for line in doc.split('\n'):
                token, tag = line.split('\t')
                tokens.append(token)
                tags.append(tag)
            token_docs.append(tokens)
            tag_docs.append(tags)
    
        return token_docs, tag_docs
    
    texts, tags = read_wnut("location/train_data.txt")
    

    【讨论】:

      【解决方案2】:

      最简单的事情是遍历文件的行,然后检索第一列。无需导入。

      result=[[]]
      with open(YOUR_FILE,"r") as input:
          for l in input:
              if not l.startswith("#"):
                  if l.strip()=="":
                      if len(result[-1])>0:
                          result.append([])
                  else:
                      result[-1].append(l.split()[0])
      result=[ " ".join(row) for row in result ]
      

      根据我的经验,手写这些是最有效的方式,因为 CoNLL 格式非常多样化(但通常以微不足道的方式,例如列的顺序)并且您不想为任何可以如此简单地解决的事情而烦恼其他人的代码。例如,@markusodenthal 引用的代码将维护 CoNLL cmets(以 # 开头的行)——这可能不是您想要的。

      另一件事是,自己编写循环允许您逐句处理,而不是先将所有内容读入数组。如果您不需要整体处理,这将更快且更具可扩展性。

      【讨论】:

        【解决方案3】:

        您可以使用 conllu 库。

        使用pip install conllu安装。

        一个示例用例如下所示。

        >>> from conllu import parse
        >>>
        >>> data = """
        # text = The quick brown fox jumps over the lazy dog.
        1   The     the    DET    DT   Definite=Def|PronType=Art   4   det     _   _
        2   quick   quick  ADJ    JJ   Degree=Pos                  4   amod    _   _
        3   brown   brown  ADJ    JJ   Degree=Pos                  4   amod    _   _
        4   fox     fox    NOUN   NN   Number=Sing                 5   nsubj   _   _
        5   jumps   jump   VERB   VBZ  Mood=Ind|Number=Sing|Person=3|Tense=Pres|VerbForm=Fin   0   root    _   _
        6   over    over   ADP    IN   _                           9   case    _   _
        7   the     the    DET    DT   Definite=Def|PronType=Art   9   det     _   _
        8   lazy    lazy   ADJ    JJ   Degree=Pos                  9   amod    _   _
        9   dog     dog    NOUN   NN   Number=Sing                 5   nmod    _   SpaceAfter=No
        10  .       .      PUNCT  .    _                           5   punct   _   _
        
        """
        >>> sentences = parse(data)
        >>> sentences
        [TokenList<The, quick, brown, fox, jumps, over, the, lazy, dog, .>]
        
        

        【讨论】:

        • 这是我一开始尝试的,但后来我得到了错误。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多