Skip to content

sklearn.externals.joblib インポートエラーの解決方法

問題の概要

scikit-learn (sklearn) を使用している際に、以下のようなインポートエラーが発生することがあります:

python
from sklearn.externals import joblib
# ImportError: cannot import name 'joblib' from 'sklearn.externals'

また、直接 import joblib を試みた場合でも、保存されたモデルファイルの読み込み時に次のエラーが発生することがあります:

ModuleNotFoundError: No module named 'sklearn.externals.joblib'

問題の原因

この問題は、scikit-learn のバージョン移行に伴う変更が原因です。scikit-learn 0.21 以降、sklearn.externals.joblib は非推奨 (deprecated) となり、バージョン 0.23 で完全に削除されました。

歴史的背景

かつて scikit-learn は内部で joblib を使用しており、sklearn.externals.joblib 経由でアクセスできましたが、現在は独立したパッケージとして扱うことが推奨されています。

解決方法

方法1: 直接 joblib をインポートする(推奨)

最も簡単な解決方法は、インポート文を変更することです:

python
# 変更前
from sklearn.externals import joblib

# 変更後
import joblib

方法2: joblib のインストール

joblib がインストールされていない場合は、以下のコマンドでインストールしてください:

bash
pip install joblib
bash
conda install joblib

方法3: 古いモデルファイルの変換

既存のモデルファイルが古い形式で保存されている場合は、一時的に古いバージョンの scikit-learn を使用して変換する必要があります:

  1. 古い環境の設定:
bash
pip install scikit-learn==0.22.2  # またはモデル作成時のバージョン
  1. モデルの変換スクリプト:
python
import sklearn.externals.joblib as extjoblib
import joblib

# 古い形式でモデルを読み込み
model = extjoblib.load('old_model.pkl')

# 新しい形式で保存
joblib.dump(model, 'new_model.pkl')
  1. 最新の環境に戻り、変換後のモデルを使用:
python
import joblib

model = joblib.load('new_model.pkl')

コード例

以下は、修正後の適切なコード例です:

python
import pandas as pd 
import numpy as np
import joblib  # sklearn.externals ではなく直接インポート
# ... 他のインポート

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)  # 直接 joblib を使用
        except:
            s3_base_path = 's3://sd-flikku/datalake/doc2vec_model'
            path = s3_base_path + '/' + model_name
            command = f"aws s3 cp {path} {model_name}".split()
            print('loading...' + model_name)
            subprocess.call(command)
            model = joblib.load(model_name)  # 直接 joblib を使用
    else:
        s3_base_path = 's3://sd-flikku/datalake/doc2vec_model'
        path = s3_base_path + '/' + model_name
        command = f"aws s3 cp {path} {model_name}".split()
        print('loading...' + model_name)
        subprocess.call(command)
        model = joblib.load(model_name)  # 直接 joblib を使用
    return model

注意点

  • バージョン 0.23 以降の scikit-learn では sklearn.externals.joblib は完全に削除されています
  • 新しいプロジェクトでは常に import joblib を使用してください
  • チームで開発している場合は、すべてのメンバーが同じアプローチを使用するようにしてください

参考情報

ヒント

モデル永続化には、最近では pickle 形式よりも ONNX 形式やモデル固有の保存形式を使用することが推奨される場合もあります。プロジェクトの要件に応じて適切な形式を選択してください。

この問題はインポート文を変更するだけで解決できる場合がほとんどですが、古いモデルファイルを扱っている場合は追加の変換作業が必要になることがあります。