1. ホーム
  2. python-3.x

[解決済み] ImportError: 'sklearn.externals' から名前 'joblib' をインポートすることができません。

2022-03-05 20:32:45

質問

S3から保存したモデルをjoblibで読み込もうとしています。

import pandas as pd 
import numpy as np
import json
import subprocess
import sqlalchemy
from sklearn.externals import joblib

ENV = 'dev'
model_d2v = load_d2v('model_d2v_version_002', ENV)

def load_d2v(fname, env):
    model_name = fname
    if env == 'dev':
        try: 
            model=joblib.load(model_name)
        except:
            s3_base_path='s3://sd-flikku/datalake/doc2vec_model'
            path = s3_base_path+'/'+model_name
            command = "aws s3 cp {} {}".format(path,model_name).split()
            print('loading...'+model_name)
            subprocess.call(command)
            model=joblib.load(model_name)
    else:
        s3_base_path='s3://sd-flikku/datalake/doc2vec_model'
        path = s3_base_path+'/'+model_name
        command = "aws s3 cp {} {}".format(path,model_name).split()
        print('loading...'+model_name)
        subprocess.call(command)
        model=joblib.load(model_name)
    return model

しかし、私はこのエラーに直面しました。

    from sklearn.externals import joblib
ImportError: cannot import name 'joblib' from 'sklearn.externals' (C:\Users\prane\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\externals\__init__.py)

次に、Joblibを直接インストールするために、次のようにしました。

import joblib

しかし、このようなエラーが発生しました。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in load_d2v_from_s3
  File "/home/ec2-user/.local/lib/python3.7/site-packages/joblib/numpy_pickle.py", line 585, in load
    obj = _unpickle(fobj, filename, mmap_mode)
  File "/home/ec2-user/.local/lib/python3.7/site-packages/joblib/numpy_pickle.py", line 504, in _unpickle
    obj = unpickler.load()
  File "/usr/lib64/python3.7/pickle.py", line 1088, in load
    dispatch[key[0]](self)
  File "/usr/lib64/python3.7/pickle.py", line 1376, in load_global
    klass = self.find_class(module, name)
  File "/usr/lib64/python3.7/pickle.py", line 1426, in find_class
    __import__(module, level=0)
ModuleNotFoundError: No module named 'sklearn.externals.joblib'

これを解決する方法を教えてください。よろしくお願いします。

解決方法は?

既存のpickle保存ファイル( model_d2v_version_002 ) は、標準的でない場所にある参照モジュールをエンコードしています。 joblib の中にある sklearn.externals.joblib というのは、トップレベルではなく

現在の scikit-learn のドキュメントでは、トップレベルの joblib - 例えば 3.4.1 永続化の例 - が、確かに 他の人の古いイシューでDeprecationWarningへの参照 scikit-learn バージョン0.21の古い scikit.external.joblib バリアントが消えていく。

Python37libsite-packages Independent Joblib_init_.py:15: DeprecationWarning: sklearn.externals.joblib は 0.21 で非推奨となり、0.21 で廃止されました。 は0.23で削除される予定です。この機能は直接インポートしてください pip install joblib でインストールできます。もし、この という警告が表示された場合、Pickle化されたモデルを読み込む際に scikit-learn 0.21+でモデルを再シリアライズしてください。

非推奨」とは、将来のリリースで廃止される可能性があるため、依存することが好ましくないものとしてマークすることです(多くの場合、常にではありませんが、同じことを行うより新しい方法が推奨されます)。

あなたの model_d2v_version_002 の古いバージョンから保存されたものです。 scikit-learn を使用するようになりました。 scikit-learn (別名 sklearn ) バージョン0.23+では、完全に sklearn.external.joblib のバリエーションがあります。従って、あなたのファイルを現在の環境に直接、または簡単に読み込むことはできません。

しかし DeprecationWarning を使えば、一時的に古い scikit-learn のバージョンで、一度古い方法でファイルを読み込んでから、現在推奨されている方法で再保存してください。警告情報を考慮すると、この場合、おそらく scikit-learn バージョン0.21.xまたは0.22.xですが、もし、あなたの model_d2v_version_002 ファイルが保存されたものであれば、それを使うようにします。手順は大体こんな感じでしょうか。

  • 一時的な作業環境を作成する(または現在の作業環境をロールバックする)には、旧来の sklearn

  • のようなインポートを行う。

import sklearn.external.joblib as extjoblib
import joblib

  • extjoblib.load() を、予定通り古いファイルから削除した後、直ちに joblib.dump() を使用して、トップレベルの joblib . (念のため、古いファイルを残しておくために、別の名前を使いたい場合があります)。

  • 実際のモダンな環境に移動/更新し、以下の作業のみを行います。 import joblib (トップレベル)を使用するために joblib.load() - コードやpickleファイルに `sklearn.external.joblib' への参照を持たなくなりました。