Проблема:
У меня есть пары предложений без точки и заглавной буквы между ними. Нужно отделить их друг от друга. Мне нужна помощь в выборе хороших функций для улучшения модели.
Справочная информация:
Я использую pycrfsuite
, чтобы выполнить классификацию последовательности и найти конец первого предложения, например:
Из коричневого корпуса я соединяю каждые два предложения и получаю их pos-теги. Затем я помечаю каждый токен в предложении 'S'
, если за ним следует пробел, и 'P'
, если за ним следует точка. Затем я удаляю точку между предложениями и опускаю следующий токен. Я получаю что-то вроде этого:
Введите:
data = ['I love Harry Potter.', 'It is my favorite book.']
Выход:
sent = [('I', 'PRP'), ('love', 'VBP'), ('Harry', 'NNP'), ('Potter', 'NNP'), ('it', 'PRP'), ('is', 'VBZ'), ('my', 'PRP$'), ('favorite', 'JJ'), ('book', 'NN')]
labels = ['S', 'S', 'S', 'P', 'S', 'S', 'S', 'S', 'S']
На данный момент я извлекаю эти общие характеристики:
def word2features2(sent, i):
word = sent[i][0]
postag = sent[i][1]
# Common features for all words
features = [
'bias',
'word.lower=' + word.lower(),
'word[-3:]=' + word[-3:],
'word[-2:]=' + word[-2:],
'word.isupper=%s' % word.isupper(),
'word.isdigit=%s' % word.isdigit(),
'postag=' + postag
]
# Features for words that are not
# at the beginning of a document
if i > 0:
word1 = sent[i-1][0]
postag1 = sent[i-1][1]
features.extend([
'-1:word.lower=' + word1.lower(),
'-1:word.isupper=%s' % word1.isupper(),
'-1:word.isdigit=%s' % word1.isdigit(),
'-1:postag=' + postag1
])
else:
# Indicate that it is the 'beginning of a sentence'
features.append('BOS')
# Features for words that are not
# at the end of a document
if i < len(sent)-1:
word1 = sent[i+1][0]
postag1 = sent[i+1][1]
features.extend([
'+1:word.lower=' + word1.lower(),
'+1:word.isupper=%s' % word1.isupper(),
'+1:word.isdigit=%s' % word1.isdigit(),
'+1:postag=' + postag1
])
else:
# Indicate that it is the 'end of a sentence'
features.append('EOS')
И поезд CRF с этими параметрами:
trainer = pycrfsuite.Trainer(verbose=True)
# Submit training data to the trainer
for xseq, yseq in zip(X_train, y_train):
trainer.append(xseq, yseq)
# Set the parameters of the model
trainer.set_params({
# coefficient for L1 penalty
'c1': 0.1,
# coefficient for L2 penalty
'c2': 0.01,
# maximum number of iterations
'max_iterations': 200,
# whether to include transitions that
# are possible, but not observed
'feature.possible_transitions': True
})
trainer.train('crf.model')
Результаты:
Отчет о точности показывает:
precision recall f1-score support
S 0.99 1.00 0.99 214627
P 0.81 0.57 0.67 5734
micro avg 0.99 0.99 0.99 220361
macro avg 0.90 0.79 0.83 220361
weighted avg 0.98 0.99 0.98 220361
Какими способами я мог бы отредактировать word2features2()
для улучшения модели? (или любая другая часть)
Вот ссылка на полный код, как сегодня.
Кроме того, я только начинающий в nlp, поэтому я бы очень оценил бы все отзывы в целом, ссылки на соответствующие или полезные источники и довольно простые объяснения. Большое спасибо!