Неправильный результат в распознавании имени объекта с BiLSTM - CRF - PullRequest
0 голосов
/ 21 марта 2019

Я пытался построить модель BiLSTM - CRF (с вложениями слов и информацией POS) для выполнения задачи NER.По некоторым причинам, независимо от того, какие параметры я пробовал, и я много пробовал, максимальная оценка f1, которую может получить моя модель, составляет около 41,5% для вьетнамцев и 35% для английского (набор данных - Conll2003).

У меня нет никакого намерения стремиться к высочайшей точности искусства, я просто пытаюсь создать себе модель NER для целей обучения.Но из исследовательских работ, которые я читал, даже самая простая модель BiLSTM (без вложений слов) может получить оценку f1 более 70%.

Последовательности обрабатываются и дополняются Tokenizer Кераса:

tokenizer = Tokenizer(lower=False, filters='!"#$%&()*+,-./:;<=>?@[\\]^`{|}~\t\n')
# Make dictionary mapping word to an integer.
tokenizer.fit_on_texts(untag_txt)
words_index = tokenizer.word_index

# Turn sentences into sequences
train_untag_txt = tokenizer.texts_to_sequences(train_untag_txt)
test_untag_txt = tokenizer.texts_to_sequences(test_untag_txt)

# Pad sentence sequences
train_untag_txt = pad_sequences(train_untag_txt, maxlen=50, padding='post', truncating='post')
test_untag_txt = pad_sequences(test_untag_txt, maxlen=50, padding='post', truncating='post')

# Pad tag sequences
train_ner_tags = np.array(pad_sequences(train_ner_tags, maxlen=50, padding='post', truncating='post', value=tag2id['OTHERS']))
test_ner_tags = np.array(pad_sequences(test_ner_tags, maxlen=50, padding='post', truncating='post', value=tag2id['OTHERS']))

Моя модель:

model = Sequential([
      Embedding(len(words_index)+1, 218,  weights=[embedding_matrix], trainable=False),
      Dropout(0.4),
      Bidirectional(LSTM(256, kernel_initializer='glorot_normal', return_sequences=True, 
                         bias_initializer='zeros', recurrent_dropout=0.4)),
      Dropout(0.4),
      Bidirectional(LSTM(256, kernel_initializer='glorot_normal', return_sequences=True, 
                         bias_initializer='zeros', recurrent_dropout=0.4)),
      Dropout(0.4),
      Bidirectional(LSTM(256, kernel_initializer='glorot_normal', return_sequences=True, 
                         bias_initializer='zeros', recurrent_dropout=0.4)),
      Dropout(0.4),
      Bidirectional(LSTM(256, kernel_initializer='glorot_normal', return_sequences=True, 
                         bias_initializer='zeros', recurrent_dropout=0.4)),
      CRF(9, kernel_initializer='glorot_normal', sparse_target=True)

Бумага, в которой я посмотрел f1 баллов различных типовмодель: https://www.aclweb.org/anthology/Q16-1026

1 Ответ

0 голосов
/ 22 марта 2019

Для тех, у кого возникла та же проблема, решение моего дела - удалить весь фильтр в токенизаторе.

От: tokenizer = Tokenizer(lower=False, filters='!"#$%&()*+,-./:;<=>?@[\\]^{|}~\t\n')

Кому: tokenizer = Tokenizer(lower=False, filters=[])

Поскольку я намеревался использовать информацию о специальных символах и теги POS, я не удалил их из набора данных. Но когда токенизатор преобразовал текст в последовательность

train_untag_txt = tokenizer.texts_to_sequences(train_untag_txt)

Он отфильтровал все эти символы, но их теги NER и POS все еще остаются и обрабатываются моделью. Я предполагаю, что это создало дисбаланс в наборах данных и меток, где слова не соответствуют их тегам NER и POS правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...