如何测试nltk资源是否已安装在运行我代码的机器上?
我刚开始我的第一个NLTK项目,对如何正确设置有点困惑。我需要一些资源,比如Punkt分词器和最大熵词性标注器。我自己是通过图形界面 nltk.download()
下载的这些资源。为了我的合作伙伴,我当然希望这些东西能自动下载。我在文档中没有找到相关的代码示例。
我是不是应该把 nltk.data.load('tokenizers/punkt/english.pickle')
这样的代码放到我的程序里?这样每次运行脚本时会不会都下载这些资源?我需要给用户(也就是我的共同开发者)反馈正在下载什么,以及为什么要花这么长时间吗?肯定有工具可以完成这个工作,对吧?:)
//编辑以澄清我的问题:
我该如何测试一个NLTK资源(比如Punkt分词器)是否已经安装在运行我代码的机器上,如果没有安装该如何进行安装?
3 个回答
2
我想分享一下我的看法,虽然有点晚了。
nltk有两个功能:download和downloader。
download()这个功能已经包含了检查包是否下载和是否是最新的逻辑:
from pathlib import Path
from nltk import download as nltk_download
from typing import List, Any
from nltk.downloader import Downloader
import logging
def download_nltk_data(
list_of_resources: List[str],
download_dir: Path,
) -> None:
for resource in list_of_resources:
nltk_download(
info_or_id=resource,
download_dir=download_dir,
quiet=True, # Change this if you wanna suppress the message
)
download_nltk_data(
list_of_resources=[
'stopwords',
'punkt',
],
download_dir=Path('./data/nltk/'),
)
输出:
[nltk_data] Downloading package stopwords to data\nltk...
[nltk_data] Package stopwords is already up-to-date!
[nltk_data] Downloading package punkt to data\nltk...
[nltk_data] Package punkt is already up-to-date!
如果你想要隐藏这些信息,只需要把quiet=True改一下就行。
如果你想对包有更细致的控制,可以使用Downloader类来扩展功能:
def check_package_exists(
package_id: Any,
download_dir: Path,
) -> bool:
downloader = Downloader(download_dir=str(download_dir))
return downloader.is_installed(package_id)
def download_nltk_data(
list_of_resources: List[str],
download_dir: Path,
) -> None:
download_dir.mkdir(parents=True, exist_ok=True)
downloader = Downloader(download_dir=str(download_dir))
for resource in list_of_resources:
if not check_package_exists(resource, download_dir):
logging.debug(f'Downloading {resource} to {download_dir}')
downloader.download(info_or_id=resource, quiet=True)
else:
logging.debug(f'{resource} already exists in {download_dir}')
download_nltk_data(
list_of_resources=[
'stopwords',
'punkt',
],
download_dir=Path('./data/nltk/'),
)
输出:
stopwords already exists in data\nltk
punkt already exists in data\nltk
或者类似的东西。
4
在Somnath的评论之后,我来分享一个使用try-except的解决方法示例。在这个例子中,我们要查找一个默认情况下不在nltk数据中的comtrans模块。
from nltk.corpus import comtrans
from nltk import download
try:
words = comtrans.words('alignment-en-fr.txt')
except LookupError:
print('resource not found. Downloading now...')
download('comtrans')
words = comtrans.words('alignment-en-fr.txt')
47
你可以使用 nltk.data.find()
这个函数,具体可以参考这个链接:https://github.com/nltk/nltk/blob/develop/nltk/data.py:
>>> import nltk
>>> nltk.data.find('tokenizers/punkt.zip')
ZipFilePathPointer(u'/home/alvas/nltk_data/tokenizers/punkt.zip', u'')
当资源不可用时,你会看到这样的错误信息:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/nltk-3.0a3-py2.7.egg/nltk/data.py", line 615, in find
raise LookupError(resource_not_found)
LookupError:
**********************************************************************
Resource u'punkt.zip' not found. Please use the NLTK Downloader
to obtain the resource: >>> nltk.download()
Searched in:
- '/home/alvas/nltk_data'
- '/usr/share/nltk_data'
- '/usr/local/share/nltk_data'
- '/usr/lib/nltk_data'
- '/usr/local/lib/nltk_data'
**********************************************************************
你可能想要这样做,以确保你的合作伙伴也有这个包:
>>> try:
... nltk.data.find('tokenizers/punkt')
... except LookupError:
... nltk.download('punkt')
...
[nltk_data] Downloading package punkt to /home/alvas/nltk_data...
[nltk_data] Package punkt is already up-to-date!
True