nltk не добавляет $NLTK_DATA к пути поиска?
Под Linux я установил env var $NLTK_DATA('/home/user/data/nltk'), и проверка работала, как и ожидалось
>>> from nltk.corpus import brown
>>> brown.words()
['The', 'Fulton', 'County', 'Grand', 'Jury', 'said', ...]
но при запуске другого скрипта Python я получил:
LookupError:
**********************************************************************
Resource u'tokenizers/punkt/english.pickle' not found. Please
use the NLTK Downloader to obtain the resource: >>>
nltk.download()
Searched in:
- '/home/user/nltk_data'
- '/usr/share/nltk_data'
- '/usr/local/share/nltk_data'
- '/usr/lib/nltk_data'
- '/usr/local/lib/nltk_data'
- u''
Как мы видим, nltk не добавляет $ NLTK_DATA в путь поиска после добавления каталога NLTK_DATA вручную:
nltk.data.path.append("/NLTK_DATA_DIR");
Сценарий работает, как и ожидалось, вопрос:
Как заставить nltk автоматически добавлять $ NLTK_DATA в путь поиска?
2 ответа
Если вы не хотите устанавливать $NLTK_DATA перед запуском ваших скриптов, вы можете сделать это в скриптах python с помощью:
import nltk
nltk.path.append('/home/alvas/some_path/nltk_data/')
Например, давайте переместим nltk_data
на нестандартный путь, который NLTK не найдет автоматически:
alvas@ubi:~$ ls nltk_data/
chunkers corpora grammars help misc models stemmers taggers tokenizers
alvas@ubi:~$ mkdir some_path
alvas@ubi:~$ mv nltk_data/ some_path/
alvas@ubi:~$ ls nltk_data/
ls: cannot access nltk_data/: No such file or directory
alvas@ubi:~$ ls some_path/nltk_data/
chunkers corpora grammars help misc models stemmers taggers tokenizers
Теперь мы используем nltk.path.append()
взломать:
alvas@ubi:~$ python
>>> import os
>>> import nltk
>>> nltk.path.append('/home/alvas/some_path/nltk_data/')
>>> nltk.pos_tag('this is a foo bar'.split())
[('this', 'DT'), ('is', 'VBZ'), ('a', 'DT'), ('foo', 'JJ'), ('bar', 'NN')]
>>> nltk.data
<module 'nltk.data' from '/usr/local/lib/python2.7/dist-packages/nltk/data.pyc'>
>>> nltk.data.path
['/home/alvas/some_path/nltk_data/', '/home/alvas/nltk_data', '/usr/share/nltk_data', '/usr/local/share/nltk_data', '/usr/lib/nltk_data', '/usr/local/lib/nltk_data']
>>> exit()
Давайте вернемся назад и посмотрим, работает ли он:
alvas@ubi:~$ ls nltk_data
ls: cannot access nltk_data: No such file or directory
alvas@ubi:~$ mv some_path/nltk_data/ .
alvas@ubi:~$ python
>>> import nltk
>>> nltk.data.path
['/home/alvas/nltk_data', '/usr/share/nltk_data', '/usr/local/share/nltk_data', '/usr/lib/nltk_data', '/usr/local/lib/nltk_data']
>>> nltk.pos_tag('this is a foo bar'.split())
[('this', 'DT'), ('is', 'VBZ'), ('a', 'DT'), ('foo', 'JJ'), ('bar', 'NN')]
Если вы действительно хотите найти nltk_data автоматически, используйте что-то вроде:
import scandir
import os, sys
import time
import nltk
def find(name, path):
for root, dirs, files in scandir.walk(path):
if root.endswith(name):
return root
def find_nltk_data():
start = time.time()
path_to_nltk_data = find('nltk_data', '/')
print >> sys.stderr, 'Finding nltk_data took', time.time() - start
print >> sys.stderr, 'nltk_data at', path_to_nltk_data
with open('where_is_nltk_data.txt', 'w') as fout:
fout.write(path_to_nltk_data)
return path_to_nltk_data
def magically_find_nltk_data():
if os.path.exists('where_is_nltk_data.txt'):
with open('where_is_nltk_data.txt') as fin:
path_to_nltk_data = fin.read().strip()
if os.path.exists(path_to_nltk_data):
nltk.data.path.append(path_to_nltk_data)
else:
nltk.data.path.append(find_nltk_data())
else:
path_to_nltk_data = find_nltk_data()
nltk.data.path.append(path_to_nltk_data)
magically_find_nltk_data()
print nltk.pos_tag('this is a foo bar'.split())
Давайте назовем этот скрипт на Python, test.py
:
alvas@ubi:~$ ls nltk_data/
chunkers corpora grammars help misc models stemmers taggers tokenizers
alvas@ubi:~$ python test.py
Finding nltk_data took 4.27330780029
nltk_data at /home/alvas/nltk_data
[('this', 'DT'), ('is', 'VBZ'), ('a', 'DT'), ('foo', 'JJ'), ('bar', 'NN')]
alvas@ubi:~$ mv nltk_data/ some_path/
alvas@ubi:~$ python test.py
Finding nltk_data took 4.75850391388
nltk_data at /home/alvas/some_path/nltk_data
[('this', 'DT'), ('is', 'VBZ'), ('a', 'DT'), ('foo', 'JJ'), ('bar', 'NN')]
Если вы хотите установить данные NLTK в среде conda и не хотите указывать расположение данных в каждом сценарии или экспортировать переменную среды, вам необходимо сделать следующее:
- Активируйте желаемую среду conda.
- Распечатать
sys.prefix
в вашей среде conda, и скопируйте этот путь (скажем,/home/dickens/envs/nltk_env
, - Бежать
nltk.download()
в среде conda выберите нужные пакеты и добавьте/share/nltk_data
на ваш путь сверху в качестве места загрузки. Например, в нашем случае это станет/home/dickens/envs/nltk_env/share/nltk_data
, - Теперь тебе пора!