Skip to content

sklearn.externals.joblib 导入错误解决方案

问题描述

当尝试从 sklearn.externals 导入 joblib 时,出现以下错误:

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

这个问题通常发生在较新版本的 scikit-learn (0.23+) 中,因为 sklearn.externals.joblib 已被弃用并移除。

解决方案

方法一:直接使用独立的 joblib 库

最简单且推荐的解决方案是直接使用独立的 joblib 包:

python
# 替换原来的导入方式
# from sklearn.externals import joblib

# 使用新的导入方式
import joblib

首先确保已安装 joblib:

bash
pip install joblib

或者使用 conda:

bash
conda install joblib

方法二:处理旧版本保存的模型文件

如果错误是由于加载旧版本 scikit-learn 保存的模型文件引起的,需要重新序列化这些模型:

注意

此方法适用于使用 sklearn.externals.joblib 保存的旧模型文件

  1. 创建一个临时环境并安装旧版本 scikit-learn (0.21.x 或 0.22.x):
bash
pip install scikit-learn==0.22.2
  1. 使用以下代码加载并重新保存模型:
python
# 在旧版本环境中执行
import sklearn.external.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 joblib
import os

# 在 Windows 上创建目录连接
os.system('mklink /J ./sklearn/externals/joblib ../joblib')

警告

这种方法只是临时解决方案,不推荐在生产环境中使用

根本原因

从 scikit-learn 0.21 版本开始,sklearn.externals.joblib 被标记为已弃用,并在 0.23+ 版本中完全移除。这是为了鼓励用户直接使用独立的 joblib 包,该包提供了更多功能和更好的维护。

迁移建议

  1. 更新导入语句:将所有 from sklearn.externals import joblib 替换为 import joblib

  2. 重新保存旧模型:使用上述方法重新序列化使用旧版本保存的模型

  3. 更新依赖:确保在 requirements.txt 或环境配置中包含 joblib 依赖

  4. 测试兼容性:在迁移后全面测试代码确保功能正常

示例代码

以下是修复后的正确代码示例:

python
import pandas as pd 
import numpy as np
import json
import subprocess
import sqlalchemy
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)  # 使用 joblib 直接加载
        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)  # 使用 joblib 直接加载
    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)  # 使用 joblib 直接加载
    return model

总结

sklearn.externals.joblib 导入错误是由于 scikit-learn 版本更新导致的兼容性问题。最好的解决方案是直接使用独立的 joblib 包并更新相关代码。对于旧版本保存的模型文件,需要先重新序列化后再在新环境中使用。

提示

始终检查并使用最新版本的库,并关注官方文档中的弃用警告,以便及时调整代码