Python nltk неправильное токенизация предложений с пользовательскими сокращениями - PullRequest
1 голос
/ 18 марта 2020

Я использую библиотеку nltk tokenize , чтобы разделить предложения sh. Многие предложения содержат сокращения, такие как e.g. или eg., поэтому я обновил токенизатор этими пользовательскими сокращениями. Я обнаружил странное поведение токенизации с предложением:

import nltk

nltk.download("punkt")
sentence_tokenizer = nltk.data.load("tokenizers/punkt/english.pickle")

extra_abbreviations = ['e.g', 'eg']
sentence_tokenizer._params.abbrev_types.update(extra_abbreviations)

line = 'Required experience with client frameworks (e.g. React, Vue.js) and testing (e.g. Karma, Tape)'

for s in sentence_tokenizer.tokenize(line):
    print(s)

# OUTPUT
# Required experience with client frameworks (e.g. React, Vue.js) and testing (e.g.
# Karma, Tape)

Так что, как вы можете видеть, токенизатор не разбивается на первую аббревиатуру (правильно), а на второе (неверно).

Странная вещь в том, что если я изменю слово Karma во всем остальном, оно будет работать правильно.

import nltk

nltk.download("punkt")
sentence_tokenizer = nltk.data.load("tokenizers/punkt/english.pickle")

extra_abbreviations = ['e.g', 'eg']
sentence_tokenizer._params.abbrev_types.update(extra_abbreviations)

line = 'Required experience with client frameworks (e.g. React, Vue.js) and testing (e.g. SomethingElse, Tape)'

for s in sentence_tokenizer.tokenize(line):
    print(s)

# OUTPUT
# Required experience with client frameworks (e.g. React, Vue.js) and testing (e.g. SomethingElse, Tape)

Любая подсказка, почему это происходит?

1 Ответ

1 голос
/ 18 марта 2020

Вы можете понять, почему пункт делает выбор перерыва, используя метод debug_decisions.

>>> for d in sentence_tokenizer.debug_decisions(line):
...     print(nltk.tokenize.punkt.format_debug_decision(d))
... 
Text: '(e.g. React,' (at offset 47)
Sentence break? None (default decision)
Collocation? False
'e.g.':
    known abbreviation: True
    is initial: False
'react':
    known sentence starter: False
    orthographic heuristic suggests is a sentence starter? unknown
    orthographic contexts in training: {'MID-UC', 'MID-LC'}

Text: '(e.g. Karma,' (at offset 80)
Sentence break? True (abbreviation + orthographic heuristic)
Collocation? False
'e.g.':
    known abbreviation: True
    is initial: False
'karma':
    known sentence starter: False
    orthographic heuristic suggests is a sentence starter? True
    orthographic contexts in training: {'MID-LC'}

Это говорит нам в корпусе, используемом для обучения, оба реагируют 'и' React 'появляются в середине предложений, поэтому они не разбиваются перед' React 'в вашей строке. Однако встречается только «карма» в нижнем регистре, поэтому он считает вероятной отправную точку предложения.

Обратите внимание, что это соответствует документации для библиотеки:

Однако Punkt предназначен для изучения параметров (список сокращений и т. Д. c.) Без присмотра из корпуса, подобного целевому домену. Поэтому предварительно упакованные модели могут быть неподходящими: используйте PunktSentenceTokenizer(text), чтобы узнать параметры из заданного текста.

PunktTrainer узнает такие параметры, как список сокращений (без контроля) из частей текста. Использование PunktTrainer напрямую допускает дополнительное обучение и модификацию гиперпараметров, используемых для определения того, что считать аббревиатурой, и т. Д. c.

Итак, быстрый взлом для этого конкретного случая настройка частного _params далее, чтобы сказать 'Карма', также может появиться в середине предложения:

>>> sentence_tokenizer._params.ortho_context['karma'] |= nltk.tokenize.punkt._ORTHO_MID_UC
>>> sentence_tokenizer.tokenize(line)
['Required experience with client frameworks (e.g. React, Vue.js) and testing (e.g. Karma, Tape)']

Вместо этого, возможно, вам следует добавить дополнительные обучающие данные из резюме, которые включают все эти имена библиотек:

from nltk.tokenize.punkt import PunktSentenceTokenizer, PunktTrainer
trainer = PunktTrainer()
# tweak trainer params here if helpful
trainer.train(my_corpus_of_concatted_tech_cvs)
sentence_tokenizer = PunktSentenceTokenizer(trainer.get_params())
...