#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, но, должно быть, я где-то допустил ошибку при этом. Еще раз спасибо!