python - 如何在 Python 上使用 Wordnet 3.1 和 NLTK?
问题描述
重要编辑
正如@Pengin 在评论中所告知的那样。NLTK 从 2022 年 1 月开始支持 WordNet 3.1。因此这个问题现在被认为是无关紧要的。
我的研究工作需要使用 Wordnet 3.1,但 NLTK (python) 附带默认的 wordnet 版本:3.0。我使用最新版本的 Wordnet 很重要。
>>> from nltk.corpus import wordnet
>>> wordnet.get_version()
'3.0'
但是,由于 NLTK 3.1 是最新版本,我找不到任何方法来下载和访问它nltk.download()
,我正在寻找一种解决方法。
正如 Wordnet 网站(此处为当前版本链接)中所写,我在下面引用:
仅限 WordNet 3.1 数据库文件
您可以下载 WordNet 3.1 数据库文件。请注意,这不是上面的完整包,也不包含任何运行 WordNet 的代码。但是,您可以用这些文件替换 3.0 本地安装的数据库目录中的文件,然后 WordNet 界面将运行,从 3.1 数据库返回条目。这只是 WordNet 3.1 数据库文件的压缩 tar 文件。
我尝试下载 Wordnet 3.1 数据库文件并将它们替换为C:\Users\<username>\AppData\Roaming\nltk_data\corpora
(在 Windows 系统上)的默认 Wordnet 文件。我怀疑它不会起作用,因为说明是在 Wordnet 软件安装中替换数据库文件,但我仍然尝试过。
在运行wordnet.get_version()
时,我收到以下错误。
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-2-d64ae1e68b36> in <module>
----> 1 wordnet.get_version()
~\anaconda3\lib\site-packages\nltk\corpus\util.py in __getattr__(self, attr)
118 raise AttributeError("LazyCorpusLoader object has no attribute '__bases__'")
119
--> 120 self.__load()
121 # This looks circular, but its not, since __load() changes our
122 # __class__ to something new:
~\anaconda3\lib\site-packages\nltk\corpus\util.py in __load(self)
86
87 # Load the corpus.
---> 88 corpus = self.__reader_cls(root, *self.__args, **self.__kwargs)
89
90 # This is where the magic happens! Transform ourselves into
~\anaconda3\lib\site-packages\nltk\corpus\reader\wordnet.py in __init__(self, root, omw_reader)
1136
1137 # Load the lexnames
-> 1138 for i, line in enumerate(self.open("lexnames")):
1139 index, lexname, _ = line.split()
1140 assert int(index) == i
~\anaconda3\lib\site-packages\nltk\corpus\reader\api.py in open(self, file)
206 """
207 encoding = self.encoding(file)
--> 208 stream = self._root.join(file).open(encoding)
209 return stream
210
~\anaconda3\lib\site-packages\nltk\data.py in join(self, fileid)
335 def join(self, fileid):
336 _path = os.path.join(self._path, fileid)
--> 337 return FileSystemPathPointer(_path)
338
339 def __repr__(self):
~\anaconda3\lib\site-packages\nltk\compat.py in _decorator(*args, **kwargs)
39 def _decorator(*args, **kwargs):
40 args = (args[0], add_py3_data(args[1])) + args[2:]
---> 41 return init_func(*args, **kwargs)
42
43 return wraps(init_func)(_decorator)
~\anaconda3\lib\site-packages\nltk\data.py in __init__(self, _path)
313 _path = os.path.abspath(_path)
314 if not os.path.exists(_path):
--> 315 raise IOError("No such file or directory: %r" % _path)
316 self._path = _path
317
OSError: No such file or directory: 'C:\\Users\\Punit Singh\\AppData\\Roaming\\nltk_data\\corpora\\wordnet\\lexnames'
然后我检查了文件结构,并在下面列出了之前和之后的树。
Wordnet 3.0 中的文件树
wordnet
├── adj.exc
├── adv.exc
├── citation.bib
├── cntlist.rev
├── data.adj
├── data.adv
├── data.noun
├── data.verb
├── index.adj
├── index.adv
├── index.noun
├── index.sense
├── index.verb
├── lexnames
├── LICENSE
├── noun.exc
├── README
├── verb.exc
Wordnet 3.1 中的文件树
wordnet
├── adj.exc
├── adv.exc
├── cntlist
├── cntlist.rev
├── cousin.exc
├── data.adj
├── data.adv
├── data.noun
├── data.verb
├── index.adj
├── index.adv
├── index.noun
├── index.sense
├── index.verb
├── log.grind.3.1
├── noun.exc
├── sentidx.vrb
├── dbfiles
├── adj.all
├── adj.pert
├── adj.ppl
├── adv.all
├── cntlist
├── noun.act
├── noun.animal
├── noun.artifact
├── noun.attribute
├── noun.body
├── noun.cognition
├── noun.communication
├── noun.event
├── noun.feeling
├── noun.food
├── noun.group
├── noun.location
├── noun.motive
├── noun.object
├── noun.person
├── noun.phenomenon
├── noun.plant
├── noun.possession
├── noun.process
├── noun.quantity
├── noun.relation
├── noun.shape
├── noun.state
├── noun.substance
├── noun.time
├── noun.Tops
├── verb.body
├── verb.change
├── verb.cognition
├── verb.communication
├── verb.competition
├── verb.consumption
├── verb.contact
├── verb.creation
├── verb.emotion
├── verb.Framestext
├── verb.motion
├── verb.perception
├── verb.possession
├── verb.social
├── verb.stative
├── verb.weather
任何有关如何将 Wordnet 3.1 与 NLTK (Python) 一起使用的建议或解决方案都会有所帮助。
提前致谢。
解决方案
经过大量搜索和反复试验,我能够在 NLTK (Python) 上使用 Wordnet 3.1。我调整了这个要点以使其工作。我在下面提供详细信息。
我将要点中提供的代码分为 3 个部分。
第 1 部分。download_extract.py
import os
nltkdata_wn = '/path/to/nltk_data/corpora/wordnet/'
wn31 = "http://wordnetcode.princeton.edu/wn3.1.dict.tar.gz"
if not os.path.exists(nltkdata_wn+'_3.0'):
os.mkdir(nltkdata_wn+'_3.0')
os.system('mv '+nltkdata_wn+"* "+nltkdata_wn+"_3.0/")
if not os.path.exists('wn3.1.dict.tar.gz'):
os.system('wget '+wn31)
os.system("tar zxf wn3.1.dict.tar.gz -C "+nltkdata_wn)
os.system("mv "+nltkdata_wn+"dict/* "+nltkdata_wn)
os.rmdir(nltkdata_wn + 'dict')
这个是用来备份现有的Wordnet 3.0文件夹wordnet
到的wordnet_3.0
,下载Wordnet 3.1数据库,放到文件夹中wordnet
。由于我使用的是 Windows 系统,因此我手动完成了此操作。
第 2 部分:create_lexnames.py
import os
nltkdata_wn = '/path/to/nltk_data/corpora/wordnet/'
dbfiles = nltkdata_wn+'dbfiles'
with open(nltkdata_wn+'lexnames', 'w') as fout:
for i,j in enumerate(sorted(os.listdir(dbfiles))):
pos = j.partition('.')[0]
if pos == "noun":
syncat = 1
elif pos == "verb":
syncat = 2
elif pos == "adj":
syncat = 3
elif pos == "adv":
syncat = 4
elif j == "cntlist":
syncat = "cntlist"
fout.write("\t".join([str(i).zfill(2),j,str(syncat)])+"\n")
lexnames
这将在文件夹中创建所需的wordnet
文件。
第 3 部分:testing_wn31.py
from nltk.corpus import wordnet as wn
nltkdata_wn = '/path/to/nltk_data/corpora/wordnet/'
# Checking generated lexnames file.
for i, line in enumerate(open(nltkdata_wn + 'lexnames','r')):
index, lexname, _ = line.split()
##print line.split(), int(index), i
assert int(index) == i
# Testing wordnet function.
print(wn.synsets('dog'))
for i in wn.all_synsets():
print(i, i.pos(), i.definition())
这测试了生成的lexname
文件,还测试了 wordnet 功能是否正常工作。
完成此过程后,我在 python 中运行以下代码,发现它实际上运行的是 3.1 版
>>> from nltk.corpus import wordnet
>>> wordnet.get_version()
'3.1'
一个谨慎的词
替换 Wordnet 3.1 数据库后,您会注意到,如果您运行以下代码
>>> import nltk
>>> nltk.download()
在下载对话框中,您将看到Corpora
选项卡下Wordnet
显示为out of date
,您不应尝试更新它,因为它会将 wordnet 替换为 3.0 版或破坏它。
推荐阅读
- rabbitmq - 网络故障后进程保留在 RabbitMQ 服务器消费者列表中
- php - 从 Windows 路径读取到 Linux 服务器时 PHP opendir 失败
- oracle - 如何为个人使用的 Oracle 数据库设置新连接?
- laravel - Laravel Eloquent 的自定义排序
- bash - 我正在尝试从我刚刚启动的实例中获取公共 IP
- javascript - axios 没有将数组保存到 MongoDB
- pandas - 永远将熊猫数据框从谷歌 colab 会话保存到我的谷歌驱动器
- sql-server - 如何每晚通过网络高速传输 100 GB 数据?
- java - 创建最终调用指定方法的 java 方法列表
- macos - 用于悬停的 Chrome 快捷方式:主要用于语法