WordNet has a hypernym / hyponym hierarchy but that is not what you want here, as you
can see when you look up goalkeeper:
from nltk.corpus import wordnet
s = wordnet.synsets('goalkeeper')[0]
s.hypernym_paths()
One of the results is:
[Synset('entity.n.01'),
Synset('physical_entity.n.01'),
Synset('causal_agent.n.01'),
Synset('person.n.01'),
Synset('contestant.n.01'),
Synset('athlete.n.01'),
Synset('soccer_player.n.01'),
Synset('goalkeeper.n.01')]
There are two methods called usage_domains()
and topic_domains()
but they return an empty list for most words:
s = wordnet.synsets('football')[0]
s.topic_domains()
>>> []
s.usage_domains()
>>> []
The WordNet Domains project however could be what you are looking for. It offers a text file that contains the mapping between Princeton WordNet 2.0 synsets and their corresponding domains. You have to register your email address to get access to the data.
Then you can read in the file that corresponds to your WordNet version (they offer 2.0 and 3.2), for example with the anydbm
module:
import anydbm
fh = open('wn-domains-2.0-20050210', 'r')
dbdomains = anydbm.open('dbdomains', 'c')
for line in fh:
offset, domain = line.split('\t')
dbdomains[offset[:-2]] = domain
fh.close()
You can then use the offset attribute of a synset to find out its domain. Maybe you have to add a zero at the beginning:
dbdomains.get('0' + str(wordnet.synsets('travel_guidebook')[0].offset))
>>> 'linguistics\n'