2015-08-26 31 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