Строки чтения, вызывающие ошибку после многих строк?

#python #nlp #named-entity-recognition #readlines

#python #nlp #распознавание именованных объектов #строки чтения

Вопрос:

В данный момент я работаю над задачей NRE с данными из wnut17train.conll (https://github.com/leondz/emerging_entities_17 ). По сути, это набор твитов, где каждая строка представляет собой одно слово из твита с прикрепленным тегом IOB (разделенным символом a t ). Разные твиты разделяются пустой строкой (на самом деле, и, как ни странно, если вы спросите меня, 'tn' строкой).

Итак, для справки, один твит будет выглядеть так:

 @paulwalk    IOBtag
...          ...
foo          IOBtag
[tn]
@jerrybeam   IOBtag
...          ...
bar          IOBtag
  

Цель этого первого шага — добиться ситуации, когда я преобразовал этот набор данных в обучающий файл, выглядящий следующим образом:

 train[0] = [(first_word_of_first_tweet, POStag, IOBtag),
(second_word_of_first_tweet, POStag, IOBtag),
...,
last_word_of_first_tweet, POStag, IOBtag)]
  

Это то, что я придумал до сих пор:

 tmp = []
train = []
nlp = spacy.load("en_core_web_sm")
with open("wnut17train.conll") as f:
    for l in f.readlines():
        if l == 'tn':
            train.append(tmp)
            tmp = []
        else:
            doc = nlp(l.split()[0])
            for token in doc:
                tmp.append((token.text, token.pos_, token.ent_iob_))
  

Все работает гладко для определенного количества твитов (или строк, пока не уверен), но после этого я получаю

 IndexError: list index out of range
  

вызвано

 doc = nlp(l.split()[0])
  

В первый раз я получил это в строке 20’000 (20’533, если быть точным), затем после проверки, что это не связано с файлом (возможно, другой способ разделения твитов или что-то в этом роде, что могло обмануть анализатор) Я удалил первые 20 000 строк и повторил попытку. Опять же, я получил ошибку примерно после строки 20’000 (20’260 — или 40’779 в исходном файле — если быть точным).

Я провел некоторое исследование readlines() , чтобы выяснить, была ли это известная проблема, но, похоже, это не так. Я что-то упускаю?

Ответ №1:

Я использовал файл wnut17train.conll из https://github.com/leondz/emerging_entities_17 и я запустил аналогичный код, чтобы сгенерировать необходимый вам результат. Я обнаружил, что в некоторых строках вместо » t n» в качестве пустой строки у нас есть только » n».

Из-за этого l.split() выдаст IndexError: индекс списка вне диапазона. Чтобы справиться с этим, мы можем проверить, равна ли длина 1, и в этом случае мы также добавляем наш tmp для обучения.

 import spacy
nlp = spacy.load("en_core_web_sm")
train = []
tmp = []
with open("wnut17train.conll") as fp:
    for l in fp.readlines():
        if l == "tn" or len(l) == 1:
            train.append(tmp)
            tmp = []
        else:
            doc = nlp(l.split("t")[0])
            for token in doc:
                tmp.append((l.split("t")[0], token.pos_, l.split("t")[1]))
  

Надеюсь, ваш вопрос решен.

Комментарии:

1. Это действительно было так. Я проверил, отличается ли какая-либо строка от шаблона ‘ t n’, используя repr, но, должно быть, я где-то допустил ошибку при этом. Еще раз спасибо!