2014-04-10 6 views
2

저는 파이썬, NLTK 및 WordNetLemmatizer를 사용하여 사전 처리기에서 작업하고 있습니다. 'bad'Python NLTK wordnet을 사용하여 'further'라는 단어를 사용합니다.

lem.lemmatize('worse', pos=wordnet.ADV) // here, we are specifying that 'worse' is an adverb 

출력 : : 여기 'worse'

글쎄, 모든 것이 괜찮 는 여기에 내가

from nltk.stem import WordNetLemmatizer 
from nltk.corpus import wordnet 
lem = WordNetLemmatizer() 
lem.lemmatize('worse', pos=wordnet.ADJ) // here, we are specifying that 'worse' is an adjective 

출력을 기대하고 있었는지 출력하는 임의의 텍스트입니다. 이 동작은 'better' (불규칙한 형태의 경우)이나 'older' (같은 테스트의 경우 'old'이 출력되지 않습니다. 그러나 wordnet은 기존의 모든 영어 단어의 철저한 목록이 아닙니다)

단어 'furter'으로 시도 할 때

내 질문은 온다 :

lem.lemmatize('further', pos=wordnet.ADJ) // as an adjective 

출력 : 'further'

lem.lemmatize('further', pos=wordnet.ADV) // as an adverb 

출력 : 'far'

이 단어는 'worse' 단어의 경우와 완전히 반대입니다.

아무도 나를 설명 할 수 있습니까? 그것은 wordnet synsets 데이터에서 오는 버그입니까, 아니면 영어 문법에 대한 오해에서 비롯된 것입니까?

질문에 이미 답변되어 있으면 google과 so를 검색했습니다. 그러나 "further"키워드를 지정하면이 단어의 인기로 인해 관련이 있지만 엉망이 될 수 있습니다.

가 사전에 감사합니다, 로맹 G.

+0

좋은 캐치 , 그리고 추가 선 :'먼 멀리'. 결과는 다음과 같습니다.'lem.lemmatize ('further', pos = wordnet.ADJ)'>>'far'. 완벽하고 고맙습니다. 대단한 답변입니다! – alvas

답변

5

WordNetLemmatizer 그에게 단어의 보조 정리에 액세스 할 수 ._morphy 함수를 사용하여; http://www.nltk.org/_modules/nltk/stem/wordnet.html에서 최소 길이의 가능한 보조 정리를 반환합니다.

def lemmatize(self, word, pos=NOUN): 
    lemmas = wordnet._morphy(word, pos) 
    return min(lemmas, key=len) if lemmas else word 

그리고 ._morphy 함수는 보조 정리를 얻기 위해 반복적으로 규칙을 적용; 규칙은 단어 길이를 줄이고 접미사를 MORPHOLOGICAL_SUBSTITUTIONS으로 대체합니다. 다음 짧은하지만 감소 된 단어와 같은 다른 단어가 있는지 본다 : 단어가 예외 목록에있는 경우

def _morphy(self, form, pos): 
    # from jordanbg: 
    # Given an original string x 
    # 1. Apply rules once to the input to get y1, y2, y3, etc. 
    # 2. Return all that are in the database 
    # 3. If there are no matches, keep applying rules until you either 
    # find a match or you can't go any further 

    exceptions = self._exception_map[pos] 
    substitutions = self.MORPHOLOGICAL_SUBSTITUTIONS[pos] 

    def apply_rules(forms): 
     return [form[:-len(old)] + new 
       for form in forms 
       for old, new in substitutions 
       if form.endswith(old)] 

    def filter_forms(forms): 
     result = [] 
     seen = set() 
     for form in forms: 
      if form in self._lemma_pos_offset_map: 
       if pos in self._lemma_pos_offset_map[form]: 
        if form not in seen: 
         result.append(form) 
         seen.add(form) 
     return result 

    # 0. Check the exception lists 
    if form in exceptions: 
     return filter_forms([form] + exceptions[form]) 

    # 1. Apply rules once to the input to get y1, y2, y3, etc. 
    forms = apply_rules([form]) 

    # 2. Return all that are in the database (and check the original too) 
    results = filter_forms([form] + forms) 
    if results: 
     return results 

    # 3. If there are no matches, keep applying rules until we find a match 
    while forms: 
     forms = apply_rules(forms) 
     results = filter_forms(forms) 
     if results: 
      return results 

    # Return an empty list if we can't find anything 
    return [] 

그러나, 그것은 exceptions에 보관 고정 된 값을 반환은, _load_exception_map 참조 http://www.nltk.org/_modules/nltk/corpus/reader/wordnet.html에서 ->badfurther -

def _load_exception_map(self): 
    # load the exception file data into memory 
    for pos, suffix in self._FILEMAP.items(): 
     self._exception_map[pos] = {} 
     for line in self.open('%s.exc' % suffix): 
      terms = line.split() 
      self._exception_map[pos][terms[0]] = terms[1:] 
    self._exception_map[ADJ_SAT] = self._exception_map[ADJ] 

, 귀하의 예를 다시 worse가는>far 따라서는 예외 목록에서이어야한다, 규칙에서 달성 될 수 없다. 예외 목록이므로 불일치가있을 수 있습니다.

예외 목록은 ~/nltk_data/corpora/wordnet/adv.exc~/nltk_data/corpora/wordnet/adv.exc에 보관됩니다.adv.exc에서

:

best well 
better well 
deeper deeply 
farther far 
further far 
harder hard 
hardest hard 

adj.exc에서 :

... 
worldliest worldly 
wormier wormy 
wormiest wormy 
worse bad 
worst bad 
worthier worthy 
worthiest worthy 
wrier wry 
... 
워드 넷 =의 특수성)
+0

그래서 당신은, 내가 파일러를 편집 한 말을 다음'adj.exc'에 –

+1

오, 간단한 수정, 제 경우에는 (Mac OS X) 예외리스트는'~/nltk_data/wordnet/*. exc' 대신'~/nltk_data/corpora/wordnet/*. exc'에 보관됩니다. –