#python #nlp #nltk #porter-stemmer
#python #nlp #nltk #porter-stemmer
Вопрос:
Я работаю над проектом, в котором я пытаюсь вычислить процент флективной морфологии нескольких корпусов, чтобы сравнить их.
Я знаю, как использовать конечный элемент Porter nltk, чтобы получить корень слова, но для меня было бы гораздо полезнее, если бы я мог возвращать аффикс, а не корень. Если бы я мог это сделать, я мог бы просто подсчитать количество аффиксов, отсеченных основой («ly», «ed» и т.д.) И сравнить это с общим количеством слов. Это может быть простое переключение, но я не могу понять, как это сделать с корнями.
Комментарии:
1. В общем, то, что вы хотите, невозможно. Например, основой слова «shy», как сообщает Porter, является «shi», что не является надлежащим подмножеством исходного слова.
2. @DYZ ты прав. Возможно, более общим автоматическим решением является поиск разницы между словами ввода и вывода. Что-то вроде «извлеките максимальную подстроку», затем используйте разницу в соответствии с конкретными потребностями. Например: porter(«shy») = «shi», затем «y»—>»i», таким образом, он помечает аффикс или их набор.
Ответ №1:
Вы уверены, что говорите о флективной морфологии? Перегиб означает, что часть речи остается неизменной, а слово изменяется только для выражения некоторых грамматических особенностей (например, прошедшего времени). Флективные аффиксы являются всегда суффиксы и, если мы не предпримем неправильные слова во внимание, существует ограниченное количество из них ( -ed
, -ing
, -er
, -est
, -s
, -es
).
Однако, похоже, что вы говорите о деривационной морфологии, потому что может быть только один флективный суффикс, поэтому для меня не имеет смысла их считать (это 0
если это лемма и 1
если это флективная форма).
Если вы говорите о производных аффиксах, то то, что вы ищете, называется сегментацией морфемы / токенизацией, и это непросто сделать, потому что на процессы словообразования влияют многие факторы и они недостаточно четко определены. В простых случаях мы просто добавляем суффикс (или предпослать префикс) к корню, однако бывают случаи, когда некоторые буквы в корне отбрасываются ( arrive
-> arrival
), изменяются ( try
-> tried
или более необычно, например assume
-> assumption
) или даже добавляются ( drama
-> dramatist
). Кроме того, вам необходимо иметь некоторую базу данных семантических знаний, потому что без нее невозможно правильно определить морфемы во всех случаях. Например, слово remember
может быть обозначено символом re-
member
. Без семантики такой морфологический анализ выглядит вполне разумным, поскольку re-
это довольно популярный префикс, означающий повторение, и member
это существующее слово. Знание семантической взаимосвязи подсказало бы нам, что member
и remember
не связаны (я полагаю, что они могут быть связаны этимологически, но на современном языке взаимосвязь не так очевидна).
Проверьте Lingua Robot и Morfessor. Первый — это API, который анализирует английский викисловарь и предоставляет данные в формате JSON. Аффиксы доступны как часть этого JSON. Morfessor — это инструмент для морфологической сегментации, поэтому он делает именно то, что вам нужно.
Ответ №2:
Что ж, если вы хотите получить аффикс, простое удаление корня (результат porter) из исходной словоформы должно сработать.
Рассмотрим этот псевдокод:
word = "hopeful"
stem_word = porter(word) # stem_word should be "hope"
affix = word.remove(stem_word) # affix should be "ful"
Другая возможная альтернатива, которая, возможно, может вам помочь, — это использовать «перенос», поскольку он потенциально может разделять слова на морфемы, а не просто разделять слово по корню. Следовательно, это могло бы дать вам больше информации о аффиксе.
Комментарии:
1. Спасибо, это имеет смысл. Однако я получаю ошибку атрибута: str не имеет атрибута remove. Есть ли другой способ удалить часть строки
2. Замените последнюю строку на
affix=word.split(stem_word)[-1]
. Это работает, только если аффикс не равен нулю.3. Привет, Уилл, да, эта ошибка вызвана тем, что «.remove» является псевдокодом (он не принадлежит ни одному языку программирования), это просто для того, чтобы показать вам идею. Если вы работаете с python, попробуйте предложение @DYZ, оно должно сработать. Тогда, если это сработает для вас, пожалуйста, не забудьте принять мой ответ 🙂