, если вы пишете
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
Прежде всего, вы можете использовать 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
.
Шаги для преобразования: Document-> Sentences-> Tokens-> POS-> Lemmas
blockquote>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)
@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)
Как и в исходном коде 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]
Вы можете создать карту, используя дефолт по умолчанию 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)
from nltk.corpus import wordnet as wn
– pragMATHiC
23 June 2018 в 22:07
Вы можете сделать это в одной строке:
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]))
.
ADJ_SAT = 's'
wordnet.princeton.edu/wordnet/man/wngloss.7WN.html – alvas 5 April 2013 в 06:52'it'
в строке"I'm loving it."
равен'PRP'
. Функция возвращает пустую строку, которую lemmatizer не принимает, и выбрасываетKeyError
. Что можно сделать в этом случае? – Clock Slave 8 March 2017 в 07:49