2015-08-26 41 views
3

我想從sklearn-learn中加載我的分類器的pkl轉儲。從AWS S3 Sklearn joblib加載函數IO錯誤

joblib轉儲比我的對象的cPickle轉儲的壓縮好得多,所以我想堅持下去。但是,嘗試從AWS S3讀取對象時出現錯誤。

案例:

  • PKL對象本地託管:和pickle.load作品,joblib.load工作
  • PKL對象被推到Heroku上與應用(負載由靜態文件夾):和pickle.load作品,JOBLIB。加載工程
  • 將Pkl對象推送到S3:pickle.load工作,joblib.load返回IOError。 (從heroku應用程序進行測試並從本地腳本進行測試)

請注意,joblib和pickle的pkl對象是使用各自方法轉儲的不同對象。 (即JOBLIB只加載joblib.dump(OBJ)和鹹菜只加載cPickle.dump(OBJ)。

JOBLIB VS cPickle的代碼

# case 2, this works for joblib, object pushed to heroku 
resources_dir = os.getcwd() + "/static/res/" # main resource directory 
input = joblib.load(resources_dir + 'classifier.pkl') 

# case 3, this does not work for joblib, object hosted on s3 
aws_app_assets = "https://%s.s3.amazonaws.com/static/res/" % keys.AWS_BUCKET_NAME 
classifier_url_s3 = aws_app_assets + 'classifier.pkl' 

# does not work with raw url, IO Error 
classifier = joblib.load(classifier_url_s3) 

# urrllib2, can't open instance 
# TypeError: coercing to Unicode: need string or buffer, instance found 
req = urllib2.Request(url=classifier_url_s3) 
f = urllib2.urlopen(req) 
classifier = joblib.load(urllib2.urlopen(classifier_url_s3)) 

# but works with a cPickle object hosted on S3 
classifier = cPickle.load(urllib2.urlopen(classifier_url_s3)) 

我的應用程序工作正常的情況下,2,但由於速度很慢加載,我想嘗試,推動所有靜態文件出來S3,特別是這些泡菜轉儲。有一些事情的方式JOBLIB負載VS泡菜,將導致此錯誤本質上的不同?

這是我的錯誤

File "/usr/local/lib/python2.7/site-packages/sklearn/externals/joblib/numpy_pickle.py", line 409, in load 
with open(filename, 'rb') as file_handle: 
IOError: [Errno 2] No such file or directory: classifier url on s3 
[Finished in 0.3s with exit code 1] 

這不是一個權限問題,因爲我已經將s3上的所有對象公開爲測試,並且pickle.dump對象加載正常。如果我直接將url輸入到瀏覽器中,joblib.dump對象也會下載。

我可能完全錯過了一些東西。

謝謝。

回答

2

joblib.load()需要文件系統上存在的文件的名稱。

Signature: joblib.load(filename, mmap_mode=None) 
Parameters 
----------- 
filename: string 
    The name of the file from which to load the object 

此外,可確保所有的公共資源可能不會對其他資產是個好主意,即使你不介意醃模型是世界訪問。

這是相當簡單的,從S3對象複製到你的工人的本地文件系統第一:

from boto.s3.connection import S3Connection 
from sklearn.externals import joblib 
import os 

s3_connection = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) 
s3_bucket = s3_connection.get_bucket(keys.AWS_BUCKET_NAME) 
local_file = '/tmp/classifier.pkl' 
s3_bucket.get_key(aws_app_assets + 'classifier.pkl').get_contents_to_filename(local_file) 
clf = joblib.load(local_file) 
os.remove(local_file) 

希望這有助於。

P.S.您可以使用這種方法來醃製整個scklearn管道,也可以使用特徵導入程序。只要注意訓練和預測之間的圖書館版本衝突。

+0

謝謝,期待如此。我查看了源代碼並看到了上面的內容,但並不清楚它意味着它必須來自相對於文件系統的路徑。 – Jasmine