Какие признаки могут помочь классифицировать окончание предложения? Классификация последовательностей

Проблема:

У меня есть пары предложений, в которых отсутствует точка и заглавная буква между ними. Нужно отделить их друг от друга. Я ищу помощи в выборе хороших функций для улучшения модели.

Задний план:

Я использую pycrfsuite для классификации последовательностей и поиска конца первого предложения, например:

Из коричневого корпуса я соединяю каждые два предложения вместе и получаю их почтовые теги. Затем я помечаю каждый токен в предложении '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(), чтобы улучшить модель? (или любую другую часть)

Вот ссылка на полный код в его нынешнем виде. .

Кроме того, я только новичок в НЛП, поэтому я был бы очень признателен за любые отзывы в целом, ссылки на соответствующие или полезные источники и довольно простые объяснения. Огромное спасибо!


person Artem Laptiev    schedule 15.04.2019    source источник


Ответы (1)


Поскольку ваши классы очень несбалансированы из-за характера проблемы, я бы предложил использовать взвешенную потерю, где потеря для тега P имеет более высокое значение, чем для класса S. Я думаю, что проблема может заключаться в том, что из-за эквивалентного веса обоих классов классификатор не уделяет достаточного внимания этим P-тегам, поскольку их влияние на потери очень мало.

Еще одна вещь, которую вы можете попробовать, — это настройка гиперпараметров, тогда обязательно оптимизируйте макрос f1-score, поскольку он будет придавать равные веса обоим классам независимо от количества экземпляров поддержки.

person Ahmed Ragab    schedule 15.04.2019
comment
Большое тебе спасибо! Вы случайно не знаете, как реализовать взвешенную потерю, используя pycrfsuite или sklearn_crfsuite? - person Artem Laptiev; 18.04.2019