NLTK word Lemmatizer странное поведение - помощь в пометке POS - Python 3 [дубликат]

, если вы пишете

int b = 0;
foo(b);

int foo(int a)
{
  a = 1;
}

, вы не меняете 'b', потому что a является копией b

, если вы хотите изменить b, вам нужно будет передать адрес из b

int b = 0;
foo(&b);

int foo(int *a)
{
  *a = 1;
}

одинаково для указателей:

int* b = 0;
foo(b);

int foo(int* a)
{
  a = malloc(10);  // here you are just changing 
                   // what the copy of b is pointing to, 
                   // not what b is pointing to
}

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

int* b = 0;
foo(&b);

int foo(int** a)
{
  *a = 1;  // here you changing what b is pointing to
}

hth

41
задан user1946217 23 March 2013 в 14:23
поделиться

6 ответов

Прежде всего, вы можете использовать nltk.pos_tag() напрямую, не обучая его. Функция загрузит предварительно обработанный теггер из файла. Вы можете увидеть имя файла с помощью nltk.tag._POS_TAGGER:

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

Поскольку он был обучен с корпусом Treebank, он также использует набор тегов Treebank .

Следующая функция будет отображать теги treebank в WordNet часть имен реплик:

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'

Проверить возвращайте значение перед передачей его в Lemmatizer, потому что пустая строка даст KeyError.

59
ответ дан Suzana 18 August 2018 в 20:06
поделиться
  • 1
    помните также спутниковые прилагательные =) ADJ_SAT = 's' wordnet.princeton.edu/wordnet/man/wngloss.7WN.html – alvas 5 April 2013 в 06:52
  • 2
    тег pos для 'it' в строке "I'm loving it." равен 'PRP'. Функция возвращает пустую строку, которую lemmatizer не принимает, и выбрасывает KeyError. Что можно сделать в этом случае? – Clock Slave 8 March 2017 в 07:49
  • 3
    Кто-нибудь знает, насколько эффективно это при обработке целых документов? – Ksofiac 26 July 2017 в 17:31
  • 4
    Я бы предпочел использовать что-то вроде ... treebank_tag [0] .lower () в качестве входных данных для pos-tag lemmatizer. В большинстве случаев это охватывает преобразование, за исключением ADJ. Но это может быть простым утверждением if – zwep 28 December 2017 в 10:28
  • 5
    @ClockSlave: Не помещайте пустые строки в lemmatizer. – Suzana 9 April 2018 в 13:01

Шаги для преобразования: Document-> Sentences-> Tokens-> 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)
4
ответ дан Deepak 18 August 2018 в 20:06
поделиться

@Suzana_K работает. Но у меня есть некоторые случаи в KeyError как упоминание @ Clock Slave.

Преобразовать теги treebank в тег Wordnet

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 

Теперь мы вводим pos только в функцию lemmatize, только если у нас есть тег wordnet

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) 
2
ответ дан Haha TTpro 18 August 2018 в 20:06
поделиться

Как и в исходном коде nltk.corpus.reader.wordnet ( http://www.nltk.org/_modules/nltk/corpus/reader/wordnet.html )

#{ Part-of-speech constants
 ADJ, ADJ_SAT, ADV, NOUN, VERB = 'a', 's', 'r', 'n', 'v'
#}
POS_LIST = [NOUN, VERB, ADJ, ADV]
7
ответ дан mousecoder 18 August 2018 в 20:06
поделиться

Вы можете создать карту, используя дефолт по умолчанию python, и воспользоваться тем, что для lemmatizer тег по умолчанию является существительным.

from nltk.stem.wordnet import WordNetLemmatizer
from nltk import word_tokenize, pos_tag
from collections import defaultdict

tag_map = defaultdict(lambda : wn.NOUN)
tag_map['J'] = wn.ADJ
tag_map['V'] = wn.VERB
tag_map['R'] = wn.ADV

text = "Another way of achieving this task"
tokens = word_tokenize(text)
lmtzr = WordNetLemmatizer()

for token, tag in pos_tag(tokens):
    lemma = lmtzr.lemmatize(token, tag_map[tag[0]])
    print(token, "=>", lemma)
2
ответ дан Shuchita Banthia 18 August 2018 в 20:06
поделиться
  • 1
    чтобы сделать этот ответ самодостаточным, помните import wn: from nltk.corpus import wordnet as wn – pragMATHiC 23 June 2018 в 22:07
  • 2
    – Shuchita Banthia 28 August 2018 в 04:18

Вы можете сделать это в одной строке:

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

Затем используйте wnpos(nltk_pos), чтобы заставить POS дать .lemmatize (). В вашем случае lmtzr.lemmatize(word=tagged[0][0], pos=wnpos(tagged[0][1])).

0
ответ дан wordsforthewise 18 August 2018 в 20:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: