Найти другую реализацию слова в строке предложения - Python

(Этот вопрос относится к проверке строк в целом, а не к обработке естественного языка как таковой, но если вы рассматриваете это как проблему НЛП, представьте, что это не тот язык, который современные анализаторы могут анализировать, для простоты я используйте английские строки, например)

скажем, есть только 6 возможных форм, в которых может быть реализовано слово.

  1. начальная буква заглавная
  2. форма множественного числа с буквой «с»
  3. его форма множественного числа с "es"
  4. с заглавной буквы + "эс"
  5. с большой буквы + "с"
  6. основная форма без множественного числа или с заглавной буквы

скажем, я хочу найти индекс 1-го экземпляра, любая форма слова coach встречается в предложении, есть ли более простой способ сделать эти 2 метода:

длинное условие

sentence = "this is a sentence with the Coaches"
target = "coach"

print target.capitalize()

for j, i in enumerate(sentence.split(" ")):
  if i == target.capitalize() or i == target.capitalize()+"es" or \
     i == target.capitalize()+"s" or i == target+"es" or i==target+"s" or \
     i == target:
    print j

повторение try-except

variations = [target, target+"es", target+"s", target.capitalize()+"es",
target.capitalize()+"s", target.capitalize()]

ind = 0
for i in variations:
  try:
    j == sentence.split(" ").index(i)
    print j
  except ValueError:
    continue

person alvas    schedule 05.11.2012    source источник
comment
№2 и №3 одинаковые. Один должен быть s, а другой es?   -  person corsiKa    schedule 05.11.2012
comment
С регулярными выражениями было бы намного проще.   -  person raina77ow    schedule 05.11.2012


Ответы (2)


Я рекомендую взглянуть на основной пакет NLTK: http://nltk.org/api/nltk.stem.html

Используя его, вы можете «удалить морфологические аффиксы из слов, оставив только основу слова. Алгоритмы выделения оснований направлены на удаление тех аффиксов, которые необходимы, например, для грамматической роли, времени, словообразовательной морфологии, оставляя только основу слова».

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

import string 

def variation(stem, word):
    return word.lower() in [stem, stem + 'es', stem + 's']

def variations(sentence, stem):
    sentence = cleanPunctuation(sentence).split()
    return ( (i, w) for i, w in enumerate(sentence) if variation(stem, w) )

def cleanPunctuation(sentence):
    exclude = set(string.punctuation)
    return ''.join(ch for ch in sentence if ch not in exclude)

def firstVariation(sentence, stem):
    for i, w  in variations(sentence, stem):
        return i, w

sentence = "First coach, here another two coaches. Coaches are nice."

print firstVariation(sentence, 'coach')

# print all variations/forms of 'coach' found in the sentence:
print "\n".join([str(i) + ' ' + w for i,w in variations(sentence, 'coach')])
person piokuc    schedule 05.11.2012
comment
это еще не язык, который поддерживается в стеммерах NLTK. - person alvas; 05.11.2012
comment
я пытаюсь построить конечную систему базы правил, которая может обеспечить высокую точность в НЛП, поэтому стеммеры на основе статистической классификации невозможны без аннотированных данных. Но NLTK должен быть первым, что нужно искать для любой задачи, связанной с NLP =) - person alvas; 05.11.2012

Морфология обычно представляет собой явление с конечным числом состояний, поэтому регулярные выражения — идеальный инструмент для ее обработки. Создайте RE, который соответствует всем случаям, с такой функцией, как:

def inflect(stem):
    """Returns an RE that matches all inflected forms of stem."""
    pat = "^[%s%s]%s(?:e?s)$" % (stem[0], stem[0].upper(), re.escape(stem[1:]))
    return re.compile(pat)

Использование:

>>> sentence = "this is a sentence with the Coaches"
>>> target = inflect("coach")
>>> [(i, w) for i, w in enumerate(sentence.split()) if re.match(target, w)]
[(6, 'Coaches')]

Если правила перегиба становятся более сложными, рассмотрите возможность использования подробных REs Python.

person Fred Foo    schedule 06.11.2012