2013-03-23 6 views
39

파이썬에서 wordnet lemmatizer를 사용하고 싶었고 pos 태그가 명시 적으로 지정되지 않은 한 기본 pos 태그가 NOUN이고 동사에 대한 올바른 보조 문자가 출력되지 않는다는 것을 알았습니다. 동사.파이썬에서 wordnet lemmatization과 pos 태그 지정

내 질문에 위의 lemmatization을 정확하게 수행하기위한 가장 좋은 방법은 무엇입니까?

nltk.pos_tag을 사용하여 pos 태그를 사용했는데, wordnet 호환 pos 태그에 트리 뱅크 pos 태그를 통합하는 데 분실했습니다. 제발 도와주세요

나는 NN, JJ, VB, RB로 출력 태그를 얻습니다. 어떻게 이것을 워드 넷 호환 태그로 바꿀 수 있습니까?

또한 nltk.pos_tag()에 태그가 지정된 코퍼스를 교육해야합니까? 아니면 평가를 위해 데이터에 직접 사용할 수 있습니까?

답변

56

먼저 훈련을하지 않고 nltk.pos_tag()을 직접 사용할 수 있습니다. 이 함수는 파일에서 미리 짜인 타거를로드합니다. 당신은 nltk.tag._POS_TAGGER와 파일 이름 을 볼 수 그것이 Treebank 영장 훈련되면서

nltk.tag._POS_TAGGER 
>>> 'taggers/maxent_treebank_pos_tagger/english.pickle' 

, 그것은 또한 Treebank tag set 사용합니다.

다음 함수는 음성 이름의 워드 넷 부분에 treebank 태그를 매핑하는 것 :

from nltk.corpus import wordnet 

def get_wordnet_pos(treebank_tag): 

    if treebank_tag.startswith('J'): 
     return wordnet.ADJ 
    elif treebank_tag.startswith('V'): 
     return wordnet.VERB 
    elif treebank_tag.startswith('N'): 
     return wordnet.NOUN 
    elif treebank_tag.startswith('R'): 
     return wordnet.ADV 
    else: 
     return '' 

그런 다음 lemmatizer와 반환 값 사용할 수의 소스 코드에서와 같이

from nltk.stem.wordnet import WordNetLemmatizer 
lemmatizer = WordNetLemmatizer() 
lemmatizer.lemmatize('going', wordnet.VERB) 
>>> 'go' 
+9

또한 위성 형용사 기억 =)'ADJ_SAT = 's'' http://wordnet.princeton.edu/wordnet/man/wngloss.7WN.html – alvas

+1

''it''에 대한 pos 태그 'm loving it.' '문자열은'PRP '입니다.이 함수는 lemmatizer가 받아들이지 않는 빈 문자열을 반환하고'KeyError'를 던집니다. 이 경우 무엇을 할 수 있습니까? –

+0

누구나 이것이 전체 문서를 처리 할 때 얼마나 효율적인지 알고 있습니까? – Ksofiac

2

@Suzana_K는 w이었다 orking. 그러나 KeyError에서 @ Clock Slave 언급이있는 경우가 있습니다. 워드 넷 태그

변환 treebank 태그

from nltk.corpus import wordnet 

def get_wordnet_pos(treebank_tag): 

    if treebank_tag.startswith('J'): 
     return wordnet.ADJ 
    elif treebank_tag.startswith('V'): 
     return wordnet.VERB 
    elif treebank_tag.startswith('N'): 
     return wordnet.NOUN 
    elif treebank_tag.startswith('R'): 
     return wordnet.ADV 
    else: 
     return None # for easy if-statement 

이제 lemmatize 기능에 우리 만 입력 POS 것은 우리가 변환 태그를

from nltk.stem.wordnet import WordNetLemmatizer 
lemmatizer = WordNetLemmatizer() 
tagged = nltk.pos_tag(tokens) 
for word, tag in tagged: 
    wntag = get_wordnet_pos(tag) 
    if wntag is None:# not supply tag in case of None 
     lemma = lemmatizer.lemmatize(word) 
    else: 
     lemma = lemmatizer.lemmatize(word, pos=wntag) 
3

단계를 워드 넷 경우에만 : 문서 수준> 문장을 -> 토큰 -> POS -> Lemmas

import nltk 
from nltk.stem import WordNetLemmatizer 
from nltk.corpus import wordnet 

#example text text = 'What can I say about this place. The staff of these restaurants is nice and the eggplant is not bad' 

class Splitter(object): 
    """ 
    split the document into sentences and tokenize each sentence 
    """ 
    def __init__(self): 
     self.splitter = nltk.data.load('tokenizers/punkt/english.pickle') 
     self.tokenizer = nltk.tokenize.TreebankWordTokenizer() 

    def split(self,text): 
     """ 
     out : ['What', 'can', 'I', 'say', 'about', 'this', 'place', '.'] 
     """ 
     # split into single sentence 
     sentences = self.splitter.tokenize(text) 
     # tokenization in each sentences 
     tokens = [self.tokenizer.tokenize(sent) for sent in sentences] 
     return tokens 


class LemmatizationWithPOSTagger(object): 
    def __init__(self): 
     pass 
    def get_wordnet_pos(self,treebank_tag): 
     """ 
     return WORDNET POS compliance to WORDENT lemmatization (a,n,r,v) 
     """ 
     if treebank_tag.startswith('J'): 
      return wordnet.ADJ 
     elif treebank_tag.startswith('V'): 
      return wordnet.VERB 
     elif treebank_tag.startswith('N'): 
      return wordnet.NOUN 
     elif treebank_tag.startswith('R'): 
      return wordnet.ADV 
     else: 
      # As default pos in lemmatization is Noun 
      return wordnet.NOUN 

    def pos_tag(self,tokens): 
     # find the pos tagginf for each tokens [('What', 'WP'), ('can', 'MD'), ('I', 'PRP') .... 
     pos_tokens = [nltk.pos_tag(token) for token in tokens] 

     # lemmatization using pos tagg 
     # convert into feature set of [('What', 'What', ['WP']), ('can', 'can', ['MD']), ... ie [original WORD, Lemmatized word, POS tag] 
     pos_tokens = [ [(word, lemmatizer.lemmatize(word,self.get_wordnet_pos(pos_tag)), [pos_tag]) for (word,pos_tag) in pos] for pos in pos_tokens] 
     return pos_tokens 

lemmatizer = WordNetLemmatizer() 
splitter = Splitter() 
lemmatization_using_pos_tagger = LemmatizationWithPOSTagger() 

#step 1 split document into sentence followed by tokenization 
tokens = splitter.split(text) 

#step 2 lemmatization using pos tagger 
lemma_pos_token = lemmatization_using_pos_tagger.pos_tag(tokens) 
print(lemma_pos_token) 
0

당신은 한 줄에이 작업을 수행 할 수 있습니다

wnpos = lambda e: ('a' if e[0].lower() == 'j' else e[0].lower()) if e[0].lower() in ['n', 'r', 'v'] else 'n' 

그런 .lemmatize을 제공하기 위해 POS를 얻을 수 wnpos(nltk_pos)()를 사용합니다. 귀하의 경우 lmtzr.lemmatize(word=tagged[0][0], pos=wnpos(tagged[0][1])).