sklearn-learn から分類子の pkl ダンプを読み込もうとしています。
joblib ダンプは、オブジェクトの cPickle ダンプよりもはるかに優れた圧縮を行うので、それを使い続けたいと思います。ただし、AWS S3 からオブジェクトを読み取ろうとするとエラーが発生します。
ケース:
- ローカルでホストされる Pkl オブジェクト: pickle.load は機能し、joblib.load は機能します
- アプリで Heroku にプッシュされた Pkl オブジェクト (静的フォルダーからロード): pickle.load は機能し、joblib.load は機能します
- S3 にプッシュされた Pkl オブジェクト: pickle.load は機能し、joblib.load は IOError を返します。(heroku アプリからのテストとローカル スクリプトからのテスト)
joblib と pickle の pkl オブジェクトは、それぞれのメソッドでダンプされる異なるオブジェクトであることに注意してください。(つまり、joblib は joblib.dump(obj) のみをロードし、pickle は cPickle.dump(obj) のみをロードします。
Joblib と 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 のロードと pickle のロード方法に本質的に異なるものはありますか?
これは私のエラーです
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オブジェクトもダウンロードされます
私は何かを完全に見逃している可能性があります。
ありがとう。