2016-06-14 27 views
2

I-Code für die Frage:Warum gibt NLTK wn.all_synsets() in Wordnet nicht eine Liste von Synsets zurück?

Wie viel Prozent der Nomen Synsets keine Hyponyme haben? Sie können alle Nomensynsets mit wn.all_synsets ('n') erhalten.

Hier ist mein Code:

import nltk 
from nltk.corpus import wordnet as wn 

all_noun = wn.all_synsets('n') 
print(all_noun) 
print(wn.all_synsets('n')) 
all_num = len(set(all_noun)) 
noun_have_hypon = [word for word in wn.all_synsets('n') if len(word.hyponyms()) >= 1] 
noun_have_num = len(noun_have_hypon) 
print('There are %d nouns, and %d nouns without hyponyms, the percentage is %f' % 
    (all_num, noun_have_num, (all_num-noun_have_num)/all_num*100)) 

, wenn ich diesen Code ausführen, der Ausgang ist

<generator object all_synsets at 0x10927b1b0>

<generator object all_synsets at 0x10e6f0bd0>

Es 82115 Substantive sind, und 16693 Substantive ohne Hyponyme, der Prozentsatz 79.671193 ist

aber wenn ändern

noun_have_hypon = [word for word in wn.all_synsets('n') if len(word.hyponyms()) >= 1]

zu

noun_have_hypon = [word for word in all_noun if len(word.hyponyms()) >= 1]

wechselt der Ausgang auf

<generator object all_synsets at 0x10917b1b0>

<generator object all_synsets at 0x10e46aab0>

Es 82115 Substantive sind, und 0 Substantive ohne Hyponyme, der Prozentsatz ist 100,000000

, warum die beiden Antworten auch nicht gleich tun, obwohl all_noun = wn.all_synsets('n'), und was ist der Sinn des 0x10927b1b0 & 0x10e6f0bd0 ?

+0

0x10927b1b0 & 0x10e6f0bd0 sind nur Speicherstellen, es bedeutet nur, dass das, was Objekt 'wordnet.all_synets()' Rückkehr tat nicht die Mühe, eine sinnvolle '__str__' Methode zu definieren. – grochmal

+0

@grochmal, hab es geschafft !!! –

Antwort

2

Es hat wenig mit NLTK zu tun, aber mehr von dem Unterschied zwischen Generator Expressions vs. List Comprehension.

Lassen Sie uns durch ein kleines Beispiel gehen:

Lassen Sie uns zuerst eine Funktion erstellen, die eine einfache Liste zurückgibt:

>>> def some_func_that_returns_a_list(): 
...  list_to_be_returned = [] 
...  for i in range(10): 
...    list_to_be_returned.append(i) 
...  return list_to_be_returned 
... 
>>> some_func_that_returns_a_list() 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Beachten Sie, dass in der some_func_that_returns_a_list()-Funktion, eine Liste erstellt werden muss und Werte eingefügt werden, bevor die Funktionen an den Platz im Code zurückkehren, der sie aufruft.

In ähnlicher Weise können wir einen Generator verwenden, um die gleiche Liste zu erreichen, die Rückkehr sein muss, aber es ist ein wenig anders, da es das yield Schlüsselwort ist mit:

>>> def some_func_that_returns_a_generator(): 
...  for i in range(10): 
...    yield i 
... 
>>> 

Beachten Sie, dass in der Funktion gibt es keine Instanziierung einer Liste, die zurückgegeben werden soll.

Und wenn Sie versuchen, die Funktion aufzurufen:

>>>some_func_that_returns_a_generator() 
<generator object some_func_that_returns_a_generator at 0x7f312719a780> 

Sie erhalten eine String-Darstellung des Generators, das heißt nur etwas, das die Funktion beschreibt. An diesem Punkt gibt es keine Werte ist instanziert und der Zeiger des Generators ist es sollte als die Funktion kleiner sein, die eine Liste instanziiert:

>>> import sys 
>>> sys.getsizeof(some_func_that_returns_a_generator()) 
80 
>>> sys.getsizeof(some_func_that_returns_a_list()) 
200 

Da Generator nicht die Werte der resultierenden Liste instanziiert Sie benötigen, es nur herausspringt die Elemente, die yield einer nach dem anderen wird, müssen Sie auf „manuell“ Schleife durch Generator, um die Liste zu erhalten, zum Beispiel:

>>> list(some_func_that_returns_a_generator()) 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> [i for i in some_func_that_returns_a_generator()] 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Aber in diesem Fall ist es die Liste „creating on-the -fly "und wenn Sie die Liste nicht stoppen, sondern die Elemente einzeln nacheinander lesen möchten, wäre ein Generator (speichertechnisch) von Vorteil.

Siehe auch:


So im Fall von NLTK wn.all_synsets() WordNet API, können Sie einfach so etwas wie:

>>> from nltk.corpus import wordnet as wn 
>>> nouns_in_wordnet = list(wn.all_synsets('n')) 

Aber beachte, dass es die ganze Liste von Synsets speichert, die Substantive im Speicher sind.

Und wenn man die Substantive mit mehr als 1 hypernym filtern möchten, können Sie vermeiden, indem Sie die filter() Funktion, um eine vollständige Liste der Substantive Instanziierung:

>>> filter(lambda ss: len(ss.hypernyms()) > 0, wn.all_synsets('n')) 

Endlich ist es zu zählen „on-the-fly "ohne die Synsets im Speicher zu speichern, können Sie tun:

>>> len(filter(lambda ss: len(ss.hypernyms()) > 0, wn.all_synsets('n'))) 
74389 

oder weniger verbosely:

>>> sum(1 for ss in wn.all_synsets('n') if len(ss.hypernyms()) > 0) 
74389 

Aber wahrscheinlich würden Sie die Synsets zugreifen möchte, so dass Sie vielleicht suchen werden:

>>> nouns_with_hyper = filter(lambda ss: len(ss.hypernyms()) > 0, wn.all_synsets('n')) 
>>> len(nouns_with_hyper) 
74389