2017-02-22 7 views
2

У меня возникают проблемы с пакетом NLTK в AWS Lambda. Однако я считаю, что проблема связана скорее с неправильной конфигурацией маршрутов в Lambda. У NLTK возникают проблемы с поиском библиотек данных, которые хранятся локально, а не являются частью установки модуля. Многие из решений, перечисленных на SO простые конфиги пути, как можно найти здесь, но я думаю, что эта проблема связана с Pathing в Lambda:Пути в AWS лямбда с Python NLTK

How to config nltk data directory from code?

What to download in order to make nltk.tokenize.word_tokenize work?

Следует также отметить, что также относится к предыдущему вопрос Я разместил здесь Using NLTK corpora with AWS Lambda functions in Python

но проблема кажется более общей, и поэтому я решил пересмотреть вопрос, поскольку он касается того, как правильно настроить среды пути в Lambda для работы с модулями, которые требуют внешние библиотеки, такие как NLTK. NLTK хранит много своих данных в папке nltk_data локально, однако, включая эту папку в zam для zambda для загрузки, она, похоже, не находит ее.

Также в FUNC почтовый файл Лямбда следующие файлы и каталоги:

\nltk_data\taggers\averaged_perceptron_tagger\averaged_perceptron_tagger.pickle 
\nltk_data\tokenizers\punkt\english.pickle 
\nltk_data\tokenizers\punkt\PY3\english.pickle 

Из следующего сайта, кажется, что уаг/задача/папка, в которой функция лямбда выполняет и у меня есть попробовал включить этот путь безрезультатно. https://alestic.com/2014/11/aws-lambda-environment/

Из документов также кажется, что существует целый ряд переменных окружения, которые могут быть использованы, однако я не знаю, как включить их в питон скрипт (приходя из окна, а не Linux) http://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html

Надеясь бросить это здесь, у любого есть опыт в настройке Лямбдинских путей. Я не видел много вопросов, связанных с этим конкретным вопросом, несмотря на поиски, так надеясь, что это может быть полезно, чтобы решить эту

код здесь

import nltk 
import pymysql.cursors 
import re 
import rds_config 
import logging 
from boto_conn import botoConn 
from warnings import filterwarnings 
from nltk import word_tokenize 

nltk.data.path.append("/nltk_data/tokenizers/punkt") 
nltk.data.path.append("/nltk_data/taggers/averaged_perceptron_tagger") 

logger = logging.getLogger() 

logger.setLevel(logging.INFO) 

rds_host = "nodexrd2.cw7jbiq3uokf.ap-southeast-2.rds.amazonaws.com" 
name = rds_config.db_username 
password = rds_config.db_password 
db_name = rds_config.db_name 

filterwarnings("ignore", category=pymysql.Warning) 


def parse(): 

    tknzr = word_tokenize 

    stopwords = ['i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', 'your', 'yours', 'yourself','yourselves', 'he', 'him', 'his', 'himself', 'she', 'her', 'hers', 'herself', 'it', 'its', 'itself', 
       'they', 'them', 'their', 'theirs', 'themselves', 'what', 'which', 'who', 'whom', 'this', 'that','these','those', 'am', 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had', 'having', 'do', 
       'does', 'did', 'doing', 'a', 'an', 'the', 'and', 'but', 'if', 'or', 'because', 'as', 'until', 'while', 'of','at', 'by', 'for', 'with', 'about', 'against', 'between', 'into', 'through', 'during', 'before', 'after', 'above', 
       'below','to', 'from', 'up', 'down', 'in', 'out', 'on', 'off', 'over', 'under', 'again', 'further', 'then','once', 'here','there', 'when', 'where', 'why', 'how', 'all', 'any', 'both', 'each', 'few', 'more', 'most', 'other', 
       'some', 'such','no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than', 'too', 'very', 's', 't', 'can', 'will','just', 'don', 'should','now', 'd', 'll', 'm', 'o', 're', 've', 'y', 'ain', 'aren', 'couldn', 'didn', 'doesn', 'hadn', 'hasn', 
       'haven', 'isn', 'ma','mightn', 'mustn', 'needn', 'shan', 'shouldn', 'wasn', 'weren', 'won', 'wouldn'] 

    s3file = botoConn(None, 1).getvalue() 
    db = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor) 
    lines = s3file.split('\n') 

    for line in lines: 

     tkn = tknzr(line) 
     tagged = nltk.pos_tag(tkn) 

     excl = ['the', 'and', 'of', 'at', 'what', 'to', 'it', 'a', 'of', 'i', 's', 't', 'is', 'I\'m', 'Im', 'U', 'RT', 'RTs', 'its'] # Arg 

     x = [i for i in tagged if i[0] not in stopwords] 
     x = [i for i in x if i[0] not in excl] 
     x = [i for i in x if len(i[0]) > 1] 
     x = [i for i in x if 'https' not in i[0]] 
     x = [i for i in x if i[1] == 'NNP' or i[1] == 'VB' or i[1] == 'NN'] 
     x = [(re.sub(r'[^A-Za-z0-9]+' + '()', r'', i[0])) for i in x] 
     sql_dat_a, sql_dat = [], [] 

журнал Выход здесь:

********************************************************************** 
    Resource u'tokenizers/punkt/english.pickle' not found. Please 
    use the NLTK Downloader to obtain the resource: >>> 
    nltk.download() 
    Searched in: 
    - '/home/sbx_user1067/nltk_data' 
    - '/usr/share/nltk_data' 
    - '/usr/local/share/nltk_data' 
    - '/usr/lib/nltk_data' 
    - '/usr/local/lib/nltk_data' 
    - '/nltk_data/tokenizers/punkt' 
    - '/nltk_data/taggers/averaged_perceptron_tagger' 
    - u'' 
**********************************************************************: LookupError 
Traceback (most recent call last): 
    File "/var/task/Tweetscrape_Timer.py", line 27, in schedule 
    server() 
    File "/var/task/Tweetscrape_Timer.py", line 14, in server 
    parse() 
    File "/var/task/parse_to_SQL.py", line 91, in parse 
    tkn = tknzr(line) 
    File "/var/task/nltk/tokenize/__init__.py", line 109, in word_tokenize 
    return [token for sent in sent_tokenize(text, language) 
    File "/var/task/nltk/tokenize/__init__.py", line 93, in sent_tokenize 
    tokenizer = load('tokenizers/punkt/{0}.pickle'.format(language)) 
    File "/var/task/nltk/data.py", line 808, in load 
    opened_resource = _open(resource_url) 
    File "/var/task/nltk/data.py", line 926, in _open 
    return find(path_, path + ['']).open() 
    File "/var/task/nltk/data.py", line 648, in find 
    raise LookupError(resource_not_found) 
LookupError: 
********************************************************************** 
    Resource u'tokenizers/punkt/english.pickle' not found. Please 
    use the NLTK Downloader to obtain the resource: >>> 
    nltk.download() 
    Searched in: 
    - '/home/sbx_user1067/nltk_data' 
    - '/usr/share/nltk_data' 
    - '/usr/local/share/nltk_data' 
    - '/usr/lib/nltk_data' 
    - '/usr/local/lib/nltk_data' 
    - '/nltk_data/tokenizers/punkt' 
    - '/nltk_data/taggers/averaged_perceptron_tagger' 
    - u'' 
********************************************************************** 
+0

Теперь это гораздо лучше вопрос =) – alvas

+0

Вопрос к вам, почему вы используете экземпляры лямбда с Windows? Разве не было бы проще развернуть сервер linux для экземпляров lambda? – alvas

+0

Кстати, амазонская лямбда позволяет вам развернуть экземпляр Windows? – alvas

ответ

2

Так что я нашел ответ на этот вопрос. После нескольких дней беспорядков я наконец понял это. Файл data.py в папке nltk необходимо изменить следующим образом. В основном удалите пути/usr/... и добавьте в папку, которую Lambda выполняет из/var/task /, и убедитесь, что ваша папка nltk_data находится в корне вашей zip-версии.

Не знаете, почему, но использование метода inline nltk.data.path.append() не работает с AWS Lambda, и файл data.py необходимо изменить напрямую.

else: 
    # Common locations on UNIX & OS X: 
    path += [ 
     str('/var/task/nltk_data') 
     #str('/usr/share/nltk_data'), 
     #str('/usr/local/share/nltk_data'), 
     #str('/usr/lib/nltk_data'), 
     #str('/usr/local/lib/nltk_data') 
    ] 
+1

Не было бы это чище: 'sys.path.append (os.path.abspath ('/ var/task/nltk_data /'))' –

4

Кажется, ваш текущий код Python работает от /var/task. Я бы предложил попробовать (не пробовал себя):

nltk.data.path.append("/var/task/nltk_data") 
+1

Это сработало для меня! Для тех, кто пытается это решить, не забудьте импортировать nltk, и вам нужно загрузить nltk corpus в свой проект в каталоге nltk_data /. – Brooks

0

Немного поздно к этой партии, но если вы посмотрите чуть выше, что фрагмент кода вставили, библиотека NLTK (v.3.2.2) дает возможность добавлять свои собственные пути в массив пути, который .

# User-specified locations: 
_paths_from_env = os.environ.get('NLTK_DATA', str('')).split(os.pathsep) 
path += [d for d in _paths_from_env if d] 

Итак, теперь, когда Lambda позволяет добавить свои собственные переменные окружения, вы можете установить переменные окружения NLTK_DATA для /var/task/nltk_data при развертывании функции и она должна работать. Однако я не тестировал его на Lambda.

Я не уверен, если Lambda разрешил переменные среды, когда вы разместили этот вопрос, но теперь это должно выполняться.

EDIT 1 Перепосещение это с некоторыми приложениями Python Я внедряющих к Lambda, я использовал решение, предложенное Мэттом выше, и он работал на меня.

nltk.data.path.append("/var/task/nltk_data")

До вызова любых функций, требующих Вещественные NLTK, вам нужно помнить, чтобы

import nltk

дополнения к этим корпусам необходимо скачать и установить в вашем проекте (за выше .append) в подкаталоге nltk_data.

При использовании virtualenv в пределах AWS Codebuild, то buildspec.yml фрагмент кода будет выглядеть следующим образом:

pre_build: 
    commands: 
    ... 
    - export HOME_DIR=`pwd` 
    - mkdir $HOME_DIR/nltk_data/ 
    - export NLTK_DATA=$HOME_DIR/nltk_data 
    - $VIRTUAL_ENV/bin/python2.7 -m nltk.downloader -d $NLTK_DATA punkt 
    ... 
Смежные вопросы