在 Python 中使用 scikit-learn 保存和加载机器学习模型

找到一个准确的机器学习模型并不是项目的终点。

在这篇文章中,您将学习如何使用 scikit-learn 在 Python 中**保存和加载您的机器学习模型**。

这允许您将模型保存到文件并在以后加载它以进行预测。

使用我的新书《使用 Python 进行机器学习》**启动您的项目**,其中包括**分步教程**和所有示例的**Python 源代码**文件。

让我们开始吧。

  • 2017年1月更新:更新以反映 scikit-learn 0.18 版本中的 API 变化。
  • **2018 年 3 月更新**:添加了下载数据集的备用链接,因为原始链接似乎已被删除。
  • 2019 年 10 月更新:修复了评论中的拼写错误。
  • 2020 年 2 月更新:更新了 joblib API。
Save and Load Machine Learning Models in Python with scikit-learn

在 Python 中使用 scikit-learn 保存和加载机器学习模型
图片由 Christine 提供,保留部分权利。

教程概述

本教程分为 3 个部分,它们是:

  1. 使用 pickle 保存您的模型
  2. 使用 joblib 保存您的模型
  3. 保存模型的技巧

使用 pickle 保存您的模型

Pickle 是 Python 中序列化对象的标准方式。

您可以使用 pickle 操作来序列化您的机器学习算法,并将序列化格式保存到文件中。

稍后您可以加载此文件以反序列化您的模型,并使用它进行新的预测。

下面的示例演示了如何在使用 Pima Indians 糖尿病发病数据集训练逻辑回归模型后,将模型保存到文件并加载它以对未见的测试集进行预测(在此处下载)。

运行示例会将模型保存到本地工作目录中的 **finalized_model.sav** 文件。

**注意**:考虑到算法或评估过程的随机性,或者数值精度的差异,您的结果可能会有所不同。请考虑运行示例几次并比较平均结果。

加载保存的模型并进行评估,可以估算出模型在未见数据上的准确性。

需要 Python 机器学习方面的帮助吗?

参加我为期 2 周的免费电子邮件课程,探索数据准备、算法等等(附带代码)。

立即点击注册,还将免费获得本课程的 PDF 电子书版本。

使用 joblib 保存您的模型

Joblib 是 SciPy 生态系统的一部分,提供了用于管道化 Python 工作的实用程序。

它提供了用于高效保存和加载使用 NumPy 数据结构的 Python 对象的实用程序。

这对于一些需要大量参数或存储整个数据集(如 K-最近邻)的机器学习算法非常有用。

下面的示例演示了如何在使用 Pima Indians 糖尿病发病数据集训练逻辑回归模型后,使用 joblib 将模型保存到文件并加载它以对未见的测试集进行预测。

运行示例会将模型保存为 **finalized_model.sav** 文件,并为模型中的每个 NumPy 数组创建一个文件(四个额外文件)。

**注意**:考虑到算法或评估过程的随机性,或者数值精度的差异,您的结果可能会有所不同。请考虑运行示例几次并比较平均结果。

加载模型后,将报告模型在未见数据上的准确性估计值。

保存模型的技巧

本节列出了完成机器学习模型时的一些重要考虑事项。

  • **Python 版本**。请注意 Python 版本。您几乎肯定需要与序列化模型时使用的 Python 版本相同的主版本(可能还有次版本)才能在以后加载和反序列化它。
  • **库版本**。在反序列化已保存模型时,您的机器学习项目中使用的所有主要库的版本几乎肯定需要保持一致。这不仅限于 NumPy 和 scikit-learn 的版本。
  • **手动序列化**。您可能希望手动输出您学习到的模型的参数,以便将来可以直接在 scikit-learn 或其他平台中使用它们。通常,机器学习算法用于进行预测的算法比用于学习参数的算法简单得多,并且可能很容易在您控制的自定义代码中实现。

请记下版本,以便如果您出于某种原因无法在以后在另一台机器或另一个平台上重新加载模型,您可以重新创建环境。

总结

在这篇文章中,您学习了如何使用 scikit-learn 在 Python 中持久化您的机器学习算法。

您学习了两种可以使用的方法:

  • 用于序列化标准 Python 对象的 pickle API。
  • 用于高效序列化包含 NumPy 数组的 Python 对象的 joblib API。

您对保存和加载模型有任何疑问吗?
请在评论中提出您的问题,我将尽力回答。

发现 Python 中的快速机器学习!

Master Machine Learning With Python

在几分钟内开发您自己的模型

...只需几行 scikit-learn 代码

在我的新电子书中学习如何操作
精通 Python 机器学习

涵盖自学教程端到端项目,例如
加载数据可视化建模调优等等...

最终将机器学习带入
您自己的项目

跳过学术理论。只看结果。

查看内容

对“使用 Python 和 scikit-learn 保存和加载机器学习模型”的 327 条回复

  1. Kayode 2016 年 10 月 18 日下午 6:15 #

    非常感谢这篇教育性文章。

    • Jason Brownlee 2016 年 10 月 19 日上午 9:17 #

      不客气,Kayode。

      • Ehsan Arabnezhad 2020 年 5 月 12 日下午 5:07 #

        如果模型和测试数据的列之间存在差异,我该如何预测?我的意思是,如果之前已经完成了一热编码步骤呢?

        • Jason Brownlee 2020 年 5 月 13 日上午 6:28 #

          如果之前从未见过某个标签,您可以忽略它,例如将其编码为全零。

      • Hamza 2020 年 8 月 18 日上午 6:33 #

        嗨,先生,我正在尝试在 Django 项目中解压缩我的模型,但遇到了值错误:缓冲区类型不匹配,预期 size_t 但得到 long long

        • Jason Brownlee 2020 年 8 月 18 日下午 1:25 #

          抱歉,我没有见过那个错误。也许可以尝试在 stackoverflow 上发布/搜索。

      • Niels Hoogeveen 2020 年 10 月 15 日上午 6:32 #

        我如何在另一个项目中加载 joblib 模型?

        我在项目 1 中训练了我的模型(带有一个自定义模块“heartdisease”),将其上传到 S3 存储桶,现在我正在尝试在项目 2 中加载 joblib 模型。但是我收到了 ModuleNotFoundError 'heartdisease',这是我在项目 1 中创建的用于预处理数据的模块。

        我在这里做错了什么?或者是否不可能转储所有依赖项?

        • Jason Brownlee 2020 年 10 月 15 日上午 7:55 #

          也许您需要当前上下文中相同的自定义代码/模块才能加载您保存的对象。

      • Vijaya 2021 年 3 月 22 日上午 1:43 #

        你好,

        使用 joblib.load() 加载巨大的模型时被终止了。
        我正在寻找解决我的问题的方法。谢谢。

        • Jason Brownlee 2021 年 3 月 22 日上午 5:32 #

          听到这个消息我很难过。

          也许您可以找出它被终止的原因?
          也许您可以尝试在另一台机器上加载?
          也许您可以尝试使用不同的库重新保存模型?

      • Vadim Sivetskiy 2021 年 7 月 23 日下午 10:22 #

        您知道是否可以将从 Matlab 解析的 Matlab 预训练模型保存到 Python 中,以便以后可以使用另一个类似的 Python .py 库调用该模型来预测值,而不再涉及 Matlab 吗?我能够使用 Matlab 引擎加载模型,但我不确定如何将此模型保存到 Python 中。描述的方法导致了“无法序列化 matlab.object 对象”等错误。

      • jamila 2022 年 9 月 8 日下午 8:21 #

        你好,
        请我想澄清一些事情。我用一个数据集训练了一个机器学习算法并进行了测试,我收到了一个很好的结果,但是如果可能的话,只为测试编写一个算法来测试新数据以避免学习阶段可以吗?
        我如何只为测试编写算法?
        谢谢。

    • Urjit 2020 年 1 月 8 日上午 12:26 #

      嘿,我训练了数字识别模型,但是当我尝试保存模型时,我收到了以下错误。请帮忙。

      import pickle

      # 将模型保存到磁盘
      filename = 'digit_model.sav'
      pickle.dump(model, open(filename, 'wb'))
      #saved_model=pickle.dumps(model)

      错误-
      —————————————————————————
      TypeError Traceback (most recent call last)
      in
      3 # 将模型保存到磁盘
      4 filename = 'digit_model.sav'
      ----> 5 pickle.dump(model, open(filename, 'wb'))
      6 #saved_model=pickle.dumps(model)

      TypeError: 无法序列化 _thread._local 对象

      • Jason Brownlee 2020 年 1 月 8 日上午 8:27 #

        很抱歉听到这个消息,也许可以尝试将您的代码和错误发布到 stackoverflow?

      • Williams Abodunrin 2020 年 3 月 27 日下午 9:34 #

        最终的模型必须以“.sav”文件扩展名保存吗?我们可以将其保存为 Python 文件(.py)吗?

        • Jason Brownlee 2020 年 3 月 28 日上午 6:17 #

          不,它是二进制文件,不是 Python 代码。

      • Harsh Buddhdev 2020 年 8 月 4 日下午 4:36 #

        如果你使用 pickle,你应该给出 .pickle 扩展名,这应该可以。

    • Mashal 2023 年 3 月 8 日下午 9:51 #

      您能告诉我如何将我在 Sckit Learn 库中训练的 ML 模型转换为 TFLite 文件,因为我想在我的 Android 应用程序中使用它。

    • Mashal 2023 年 3 月 8 日下午 9:53 #

      您能告诉我如何将我在 Sckit Learn 库中训练的 ML 模型转换为 TFLite 文件,因为我想在我的 Android 应用程序中使用它。

  2. TonyD 2016 年 11 月 13 日下午 3:52 #

    嗨,Jason,

    我有你的两本书,它们太棒了。我之前参加过几门机器学习课程,但正如你所说,它们更侧重于理论而不是实践。我如饥似渴地读完了你的《Python 机器学习》一书,与我参加过的课程相比,我的技能提高了 20 倍。

    我通过 Google 搜索你的书第 17 章中的一段代码找到了这个页面。这行代码

    loaded_model = pickle.load(open(filename, 'rb'))

    抛出错误

    runfile('C:/Users/Tony/Documents/MassData_Regression_Pickle.py', wdir='C:/Users/Tony/Documents')
    文件“C:/Users/Tony/Documents/MassData_Regression_Pickle.py”,第 55 行
    loaded_model = pickle.load(open(filename, 'rb'))
    ^
    SyntaxError: invalid syntax

    • Jason Brownlee 2016 年 11 月 14 日上午 7:36 #

      谢谢 TonyD。

      我想知道是否有复制粘贴错误,比如多余的空格什么的?

      书中为该章节提供的代码示例(.py文件)对您有用吗?

    • William 2019 年 1 月 7 日下午 9:37 #

      正如 Jason 已经说过的,这是一个复制粘贴问题。在你的那行代码中,引号是问题所在。

      loaded_model = pickle.load(open(filename, 'rb'))

      应该是

      loaded_model = pickle.load(open(filename, 'rb'))

      尝试理解其中的区别 :).

    • John 2020 年 1 月 8 日下午 1:15 #

      嘿 TonyD
      如果您不介意,可以分享这些书给我吗?

      我非常渴望学习机器学习,但我买不起这些书。如果您能帮助我获得这些书,那将非常棒。

  3. Konstantin 2016 年 11 月 19 日上午 6:01 #

    你好,Jason

    我们“稍后”在哪里可以获取 X_test, Y_test?它被“垃圾回收”了!
    在您的示例中,X_test, Y_test 没有被 pickle,您只 pickle 了分类器,但您仍然引用了 x 和 y。实际应用程序不是单一流程,我找到了解决方法,并从 clf.classes_ 对象中获取了 Y。

    正确的解决方案是什么?我们应该将带有 X 和 Y 的装饰器类 pickle 吗,还是使用 pickle 过的分类器来拉取 Y 值?我在 KNeighborclassifier(我的示例)的文档中也没有找到合法信息;如何从分类器中拉取 Y 值。

    您能给些建议吗?

    • Jason Brownlee 2016 年 11 月 19 日上午 8:51 #

      嗨,Konstantin,

      我不建议保存数据。其目的是演示如何加载模型并将其用于新数据——我只是出于演示目的使用现有数据。

      将来加载模型时,您可以从文件中加载新数据,并使用这些新数据进行预测。

      如果您也有预期值(y),您可以将预测结果与预期值进行比较,以查看模型表现如何。

      • Guangping Zhang 2016 年 11 月 21 日上午 6:01 #

        我是 Python 新手,你的代码完美运行!但是保存的文件在哪里?我用的是 Windows 10。

        • Jason Brownlee 2016 年 11 月 22 日上午 6:56 #

          谢谢广平。

          保存文件在您的当前工作目录中,从命令行运行时。

          如果您使用的是笔记本或 IDE,我不知道文件放在哪里。

    • Jun Chang 2022 年 5 月 5 日下午 10:44 #

      我认为您可以跳过代码行:loaded_model.score(X_test, Y_test),只需像这样预测您的新数据:loaded_model.predict(newdataset)

  4. Mohammed Alnemari 2016 年 12 月 13 日下午 2:45 #

    嗨,Jason,
    我只是想知道我们是否可以使用 Yaml 或 Json 与 sklearn 库。我尝试了很多次,但无法找到答案。我尝试按照你的 Kares 课程来做,但由于某种原因它不起作用。希望你能帮我看看是否可行。

    • Jason Brownlee 2016 年 12 月 14 日上午 8:24 #

      嗨,穆罕默德,我相信将模型序列化为 yaml 和 json 是 Keras 库特有的。

      sklearn 序列化专注于二进制文件,如 pickle。

  5. Normando Zubia 2016 年 12 月 29 日上午 9:55 #

    嗨,我叫 Normando Zubia,我一直在阅读您的许多材料用于我的学校课程。

    我目前正在开发一个模型,用于预测生产环境中的用户行为。由于多种情况,我无法将模型保存为 pickle 文件。您知道有什么方法可以将模型保存为 json 文件吗?

    我一直在玩 sklearn 类,我注意到如果我在 OneHotEncoding 模型中保存一些参数,例如:n_values_、feature_indices_ 和 active_features_,我就可以重现结果。这可以用管道完成吗?或者您认为我需要保存每个模型的参数来加载每个模型?

    附言:对我的英语不好表示抱歉,感谢您的关注。

    • Jason Brownlee 2016 年 12 月 30 日上午 5:49 #

      嗨,诺曼多,

      如果您的模型简单,您可以将系数直接保存到文件。然后您可以尝试稍后将它们放回新模型中,或者自己实现算法的预测部分(对于大多数方法来说非常容易)。

      告诉我进展如何。

  6. Samuel 2017 年 2 月 6 日下午 3:14 #

    你好 Jason,

    我是机器学习新手。我是您的忠实粉丝,阅读了您的大量博客和书籍。非常感谢您教我们机器学习。

    我尝试过 pickle 我的模型,但失败了。我的模型使用 VGG16 并替换了顶层用于我的分类解决方案。我进一步缩小了问题范围,发现是 VGG16 模型未能 pickle。请在下面找到我简化的代码和错误日志

    如果您能给我一些解决此错误的方向,我将不胜感激。

    非常感谢
    ———————————————————-
    # 使用 Pickle 保存模型
    from keras.applications.vgg16 import VGG16
    import pickle

    model = VGG16(weights='imagenet', include_top=False)

    filename = 'finalized_model.sav'
    pickle.dump(model, open(filename, 'wb'))

    —————————————————-
    /Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /Users/samueltin/Projects/bitbucket/share-card-ml/pickle_test.py
    使用 TensorFlow 后端。
    回溯(最近一次调用)
    文件“/Users/samueltin/Projects/bitbucket/share-card-ml/pickle_test.py”,第 8 行,在
    pickle.dump(model, open(filename, 'wb'))
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 1376 行,在 dump
    Pickler(file, protocol).dump(obj)
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 224 行,在 dump
    self.save(obj)
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 331 行,在 save
    self.save_reduce(obj=obj, *rv)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 425 行,在 save_reduce
    保存(state)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 606 行,在 save_list
    self._batch_appends(iter(obj))
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 621 行,在 _batch_appends
    保存(x)
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 331 行,在 save
    self.save_reduce(obj=obj, *rv)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 425 行,在 save_reduce
    保存(state)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 606 行,在 save_list
    self._batch_appends(iter(obj))
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 621 行,在 _batch_appends
    保存(x)
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 331 行,在 save
    self.save_reduce(obj=obj, *rv)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 425 行,在 save_reduce
    保存(state)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 331 行,在 save
    self.save_reduce(obj=obj, *rv)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 425 行,在 save_reduce
    保存(state)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 331 行,在 save
    self.save_reduce(obj=obj, *rv)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 425 行,在 save_reduce
    保存(state)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 606 行,在 save_list
    self._batch_appends(iter(obj))
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 621 行,在 _batch_appends
    保存(x)
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 331 行,在 save
    self.save_reduce(obj=obj, *rv)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 425 行,在 save_reduce
    保存(state)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 331 行,在 save
    self.save_reduce(obj=obj, *rv)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 425 行,在 save_reduce
    保存(state)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py”,第 331 行,在 save
    self.save_reduce(obj=obj, *rv)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 425 行,在 save_reduce
    保存(state)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 606 行,在 save_list
    self._batch_appends(iter(obj))
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 621 行,在 _batch_appends
    保存(x)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 568 行,在 save_tuple
    保存(element)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 286 行,在 save
    f(self, obj) # 使用显式 self 调用未绑定方法
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 655 行,在 save_dict
    self._batch_setitems(obj.iteritems())
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 669 行,在 _batch_setitems
    保存(v)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/pickle.py”,第 306 行,在 save
    rv = reduce(self.proto)
    文件“/Library/Frameworks/Python.2.7/lib/python2.7/copy_reg.py”,第 70 行,在 _reduce_ex
    抛出 TypeError,“无法序列化 %s 对象” % base.__name__
    TypeError: 无法序列化模块对象

    进程以退出代码 1 结束

    • Jason Brownlee 2017 年 2 月 7 日上午 10:11 #

      抱歉,Samuel,我之前没有尝试过保存预训练模型。我没有好的建议给您。

      告诉我进展如何。

      • huikang 2018 年 9 月 21 日上午 11:50 #

        在机器学习中,有没有比 joblib.load() 更高效的方法,直接将模型存储在内存中并再次使用它?

        • Jason Brownlee 2018 年 9 月 21 日下午 2:21 #

          当然,您可以创建一个内存副本。我认为 sklearn 有一个 clone() 函数可以使用。

  7. Amy 2017 年 3 月 8 日上午 7:03 #

    我使用 liblinearutils 训练了一个模型。该模型无法使用 pickle 保存,因为它会报错说带有指针的 ctype 模块无法被 pickle。我该如何保存我的模型?

    • Jason Brownlee 2017 年 3 月 8 日上午 9:47 #

      抱歉 Amy,我没有任何具体的例子可以帮助你。

      或许你可以将模型的系数保存到文件中?

  8. SHUBHAM BHARDWAJ 2017 年 4 月 3 日下午 10:42 #

    非常感谢,非常有用

  9. Benju 2017 年 4 月 11 日上午 1:35 #

    我保存的模型有 500MB+ 大小……这正常吗?

    • Jason Brownlee 2017 年 4 月 11 日上午 9:34 #

      哎呀,听起来确实很大。

      如果您的模型很大(有很多层和神经元),那么这样做可能才有意义。

  10. Anupam 2017年4月13日 凌晨2:32 #

    如何使用模型文件(“finalized_model.sav”)测试未知数据。例如,如果模型用于标注器,这个模型将如何标注文本文件数据?有没有例子?

    • Jason Brownlee 2017年4月13日 上午10:08 #

      您可以加载已保存的模型并开始进行预测(例如 yhat = model.predict(X))。

      请参阅这篇关于模型定稿的帖子。
      https://machinelearning.org.cn/train-final-machine-learning-model/

      • kerolus momtaz HIE 2020年7月24日 上午8:58 #

        当我尝试运行此代码时,出现此错误,您能帮我吗?

        {AttributeError: ‘int’ object has no attribute ‘predict’}

        import numpy as np
        import pretrainedmodels
        import torch
        import torch.nn as nn
        import pickle
        import base64
        import cv2
        from PIL import Image
        import io

        with open(“picture.png”, “rb”) as file
        data = base64.b64encode(file.read()).decode()

        print(type(data))
        #img deconversion from base64 to np array

        decoded_data = base64.b64decode(data)
        np_data = np.fromstring(decoded_data,np.uint8)
        img = cv2.imdecode(np_data,cv2.IMREAD_UNCHANGED)
        loaded_model = pickle.load(open(“densenet.pkl”, “rb”))
        label = loaded_model.predict(img)
        print (label)

  11. Oss Mps 2017年4月21日 下午3:09 #

    尊敬的先生,请问如何从pickle dump中提取权重?谢谢

    • Jason Brownlee 2017年4月22日 上午9:23 #

      我建议直接从模型中提取系数,并以您喜欢的格式保存它们。

  12. Suhas 2017年5月24日 凌晨4:44 #

    您好,我喜欢您的网站;它非常有用!

    有没有示例展示如何在例如100个epoch/迭代后保存模型的训练?从joblib或scikit learn中查看并不立即清楚。

    这在处理大型数据集和/或可能不可靠的计算机或集群(例如,容易发生系统重启等)时尤其有用。

    • Jason Brownlee 2017年5月24日 凌晨4:59 #

      我不确定如何使用sklearn做到这一点。您可能需要编写一些自定义代码。考虑发布到stackoverflow。

  13. Viktor 2017年5月30日 上午8:52 #

    嘿!
    是否可以在未安装sklearn的云服务器上打开我保存的模型并进行预测?

    • Jason Brownlee 2017年6月2日 下午12:31 #

      不。

      您可以改为从模型中保存系数并编写自己的自定义预测代码。

  14. Clemence 2017年6月8日 下午6:55 #

    你好 Jason,非常感谢,这非常有帮助。

    你知道是否可以和ML模型一起加载特征转换吗?
    我主要考虑的是分类变量,我们需要将其编码成数值变量。

    我使用sklearn来做这个,但我不知道我们是否可以(像Spark那样),将这种转换与ML模型集成到序列化文件(Pickle或Joblib)中。

    #将分类变量编码为数值变量
    from sklearn.preprocessing import LabelEncoder
    list_var = [‘country’, ‘city’]

    encoder = LabelEncoder()
    for i in list_var
    df[i] = encoder.fit_transform(df[i])

    然后我在训练数据集上拟合模型…

    我需要将这个转换与模型一起保存。你知道这是否可能吗?
    谢谢!

    • Jason Brownlee 2017年6月9日 上午6:23 #

      抱歉,我不太明白。

      您可以为模型转换数据,将来加载模型时也可以应用相同的转换。

      您可以使用pickle保存转换对象。您是这个意思吗?

  15. Bhavani Shanker 2017年6月22日 凌晨1:24 #

    嗨,Jason,
    请接受我对您关于使用Python进行机器学习的精彩演讲的赞扬。

    **********************************************
    # 将模型保存到磁盘
    filename = 'finalized_model.sav'
    joblib.dump(model, filename)

    # 稍后...

    # 从磁盘加载模型
    loaded_model = joblib.load(filename)
    result = loaded_model.score(X_test, Y_test)
    print(result)
    *******************************************************

    保存模型“finalized_model.sav”后,如何在新会话中稍后调出保存的模型?

    如果您能在这方面提供建议,我将不胜感激。

  16. jinsh 2017年6月28日 晚上8:57 #

    你好,先生,

    以上代码保存了模型,稍后我们也可以检查准确性
    但我需要做什么来预测未知数据的类别呢?
    我的意思是应该调用哪个函数?

    例如:2,132,40,35,168,43.1,2.288,33

    您能建议如何通过预测获取上述数据的类别吗?

    谢谢你

    • Jason Brownlee 2017年6月29日 上午6:35 #

      将输入数据传递给预测函数并使用结果。

      • Vaibhhav Jadhav 2022年1月21日 下午4:18 #

        您好 Jason,我已经在 Azure Studio 中训练了时间序列模型。数据集有 106 列(105 列不包括目标列,索引 = 年)。我使用了所有数据点来训练模型。现在,在获得最佳训练模型后,我可以下载 pickle 文件。现在,我该如何使用这个 pickle 文件呢?我应该向这个 pickle 文件传递哪些输入以获得下一个预测?谢谢。

        • James Carmichael 2022年1月22日 上午10:53 #

          您好 Vaibhhav… 我不确定我是否理解您的问题。请澄清一下,以便我更好地协助您。

  17. Ukesh Chawal 2017年7月24日 晚上11:09 #

    我们可以使用“pickling”来保存LSTM模型,并加载或使用硬编码的预训练模型根据传入的数据生成预测来初始化模型吗?

    当我尝试使用它时,它给我以下错误:

    PicklingError: Can’t pickle : attribute lookup module on builtins failed

  18. akatsuki 2017年8月9日 下午1:21 #

    说实话,这是网上最好的网站。太棒了!
    我喜欢你的电子邮件订阅,作为初学者,它们对我有很大帮助。

  19. vikash 2017年8月10日 晚上9:32 #

    您好 @Jason Brownlee,感谢您的这篇富有启发性的博客。您能否指导我解决一个问题,我希望只使用新数据集和新类别来重新训练 .pkl 模型,同时保持之前的学习不变。我原以为 model.fit(dataset,label) 可以做到,但它会忘记之前的学习。请您给我一些技巧。
    谢谢

    • Jason Brownlee 2017年8月11日 上午6:42 #

      抱歉,我没听懂。您能重新提问吗?

      • sassashi 2017年8月28日 凌晨4:41 #

        你好 Jason,我相信 @vikash 正在寻找一种方法,在初始训练阶段之后,用新的示例持续训练模型。这也是我正在寻找的东西。我知道在tensorflow中可以用新的示例重新训练模型,但我不确定sklearn是否可以。

        进一步扩展问题:1-您使用 sklearn 训练模型 2-使用 pickle 或 joblib 保存模型
        3-然后您得到了一些在初始训练“步骤1”时不可用的新示例 4-您加载之前的模型 5-现在您尝试使用新数据再次训练模型,而不丢失之前的知识… 步骤5在sklearn中是否可能?

  20. Navdeep Singh 2017年8月22日 晚上8:30 #

    嗨,Json,

    我需要您指导如何用新的训练数据更新已保存的pickle文件。

    我回忆起3种方法:在线学习,即每当有新的观察结果时训练一次,在这种情况下模型总是偏向于新特征,这不是我想要的。

    第二种是,每当有一组n个观察结果时,将其与之前的数据嵌入并从头开始重新训练,这不是我想要的,因为在实时环境中会花费大量时间。

    第三种是小批量学习,我知道一些算法(如SGD和其他算法)使用部分拟合方法并做同样的事情,但我还有其他算法,如随机森林、决策树、逻辑回归。我想问是否可以用新的训练数据更新之前训练过的pickle?

    我正在进行文本分类,我读到这样做可能会导致模型更新的pickle无法获取新数据的新特征(使用tfidf或countvectorizer创建),这帮助不大。

    此外,由于领域相同,如果客户端(我们正在从事的项目)不同,我是否可以使用旧客户端训练的模型pickle,并用新客户端数据进行训练来更新它。基本上我正在进行迁移学习。

    • Jason Brownlee 2017年8月23日 上午6:48 #

      很好的问题。

      这是一个具有挑战性的问题。实际上,解决方案必须针对您的项目需求而定。

      一种灵活的方法可能是,在编码中内置容量,以允许将来出现新词。

      最简单的方法是忽略新词。

      这些以及其他策略都是可测试的。通过带外测试数据,查看两种方案下的性能如何下降。

  21. Merari 2017年9月11日 上午7:59 #

    感谢分享,
    有没有办法只用保存的模型对新数据进行预测?从新文件调用此模型?我尝试了最后一条指令

    # 从磁盘加载模型
    loaded_model = pickle.load(open(filename, 'rb'))
    result = loaded_model.score(X_test, Y_test)
    print(result)

    但我没有成功

    373/5000
    感谢分享,
    有没有办法只使用保存的模型对新数据进行预测?从新文件调用这个模型?我尝试了最终指令

    # 从磁盘加载模型
    loaded_model = pickle.load (open (filename, ‘rb’))
    result = loaded_model.score (X_test, Y_test)
    print (result)

    但我没有成功。

    • Jason Brownlee 2017年9月11日 下午12:11 #

      这正是我们在这个教程中所做的。

      问题究竟是什么?

  22. AP 2017年9月29日 上午6:36 #

    您好 Jason,我从阅读您的Python书籍和博客中学到了很多。感谢您所做的一切。

    当我使用加载的模型在不同的会话中处理文本数据时,我遇到了一个问题。我使用CountVectorizer和Tfidf对训练数据进行拟合和转换。然后我像往常一样只用拟合的实例转换测试数据。但是,当在不同的会话中使用加载的预训练模型时,我在特征提取方面遇到了问题。我无法直接转换测试数据,因为它需要当前会话中不存在的拟合实例。如果我只在测试数据上进行拟合和转换,模型预测性能会急剧下降。我相信这不是进行机器学习的正确方法。那么,在使用之前训练过的模型时,我如何使用CountVectorizer、Tfidf或其他方法进行特征提取呢?

    我正在使用Spark ML,但我认为对于scikit-learn也一样。

    • Jason Brownlee 2017年9月30日 上午7:31 #

      也许您也可以将数据转换对象pickle化,并在第二个会话中重新使用它们?

  23. Bhavya Chugh 2017年10月29日 凌晨5:57 #

    嗨,Jason,

    我训练了一个随机森林模型,并将其保存为pickle文件在我的本地桌面。然后我将该pickle文件复制到我的远程服务器并用相同的文件测试了模型,但它给出了不正确的预测。我在本地使用python 3.6,在远程使用python 3.4,但是scikit-learn的版本相同。有什么想法为什么会这样吗?

    • Jason Brownlee 2017年10月29日 凌晨6:00 #

      不知道,也许看看实验是否能在同一台机器上复制?或者在不同机器上使用相同版本的Python?

  24. Berkin Albert Antony 2017年11月10日 下午5:45 #

    嗨,Jason Brownlee,

    我有一个用于二分类的LogisticRegression模型。我希望在给定测试数据点的情况下,在训练过的模型中找到相似的数据点。这样我就可以展示这些相似的数据点是以相同类别预测的。

    您能就此提出您的想法吗?我正在使用scikit learn的逻辑回归。

    谢谢

    • Jason Brownlee 2017年11月11日 上午9:18 #

      也许您可以找到彼此欧几里得距离较小的数据点?

  25. James 2017年11月16日 上午8:47 #

    嗨,Jason –

    如果您对特征子集训练的模型进行pickle,是否可以在将pickle模型加载到不同文件后查看这些特征?例如:原始df具有特征a,b,c,d,e,f。您在a,c,e上训练模型。是否可以在单独的脚本中加载pickle模型并查看模型是在a,c,e上训练的?

    谢谢,
    James

    • Jason Brownlee 2017年11月16日 上午10:33 #

      是的,您可以保存模型、加载模型,然后用它对新数据进行预测。

  26. Mrinal Mitra 2017年11月22日 凌晨6:26 #

    嗨,Jason,

    感谢您如此详细的解释。我是初学者,需要您的指导。我使用数据训练了模型。现在我希望这个模型能预测一个未经测试的数据集。然而,我的要求是一个输出,它将包含数据和模型对应的预测。例如,记录1 - 类型a,记录2 - 类型a,记录3 - 类型c,依此类推。您能指导我一下吗?

  27. Niranjan 2017年12月3日 下午3:22 #

    你好,

    我正在使用pandas中读取csv方法的chunk功能,并尝试迭代地构建模型并保存它。但它总是保存最后一个chunk中构建的模型,而不是整个模型。您能帮我解决这个问题吗?

    clf_SGD = SGDClassifier(loss=’modified_huber’, penalty=’l2′, alpha=1e-3, max_iter=500, random_state=42)
    pd.read_csv(“file_name”,chunksize = 1000)
    """
    数据准备和清洗
    """
    hashing = hv.fit_transform(X_train[‘description’])
    clf_SGD.partial_fit(hashing, y_train, classes= y_classes)

    joblib.dump(clf_SGD, source_folder + os.path.sep+’text_clf_sgd.pkl’)

    • Jason Brownlee 2017年12月4日 上午7:46 #

      抱歉,我不太明白,您能试着重新表达您的问题吗?

  28. Shabbir 2017年12月8日 上午8:50 #

    嗨,Jason,
    这非常有帮助,并为我节省了相当多的处理时间。

    我正在对250MB的数据训练一个随机森林分类器,每次训练需要40分钟,但结果如要求的那样准确。joblib方法创建了一个4GB的模型文件,加载时间缩短到7分钟。这很有帮助,但结果变得不准确,或者至少与原始结果相差很大。我使用2个决策树和1个随机森林的平均值来构建模型。决策树模型在加载和训练方面保持了一致性,但随机森林没有。有什么想法吗?

  29. Nilanka 2017年12月19日 晚上9:10 #

    谢谢,很有用!

  30. Gokhan 2017年12月28日 下午2:55 #

    你好,如果我加载模型
    loaded_model = joblib.load(filename)
    result = loaded_model.score(X_test, Y_test)
    print(result)

    我可以用这个模型对其他测试集进行预测吗?

  31. Vinay Boddula 2018年1月20日 凌晨5:31 #

    嗨,Jason,

    我如何生成新的 X_Test 进行预测?这个新的 X_Test 需要确保传递的参数与模型训练时使用的参数相同。

    背景:我基本上是保存模型并时不时地用新值进行预测。我们如何检查新值是否具有所有参数和正确的数据类型。

    • Jason Brownlee 2018年1月20日 上午8:25 #

      可视化和统计。

      我有很多关于这个主题的帖子,可以尝试搜索框。

  32. Sekar 2018年2月1日 凌晨4:06 #

    Jason。非常好的文章。正如其他人所问,在我的案例中,我使用DecisionTreeClassifier进行文本特征到整数的转换。尽管您提到转换映射也可以被选择并读取回来,但有没有可用的示例?它会存储在同一个文件中还是另一个文件中?

  33. Yousif 2018年2月5日 晚上8:01 #

    非常感谢教授
    我们学到了更多新知识

  34. Adarsh C 2018年2月8日 下午12:29 #

    你好,先生,
    我想将预测输出保存为CSV文件。在完成ML变量后,我想保存“y_predicted”。我正在使用Python IDE 3.5.x,我有pandas、sklearn、tensorflow库。

  35. Atul 2018年3月11日 凌晨6:45 #

    嗨,Jason,

    我想将预测输出保存为CSV文件。在完成ML变量后,我想保存“y_predicted”。我如何将朴素贝叶斯、SVM、RF和DT分类的最终预测保存为.csv文件,其中包含三列:样本、实际值、预测

  36. Tommy 2018年3月22日 晚上11:14 #

    我有一篇论文中的回归系数列表。有没有办法将这些系数加载到sklearn逻辑回归函数中,以尝试复现他们的模型?
    谢谢!
    Tommy

    • Jason Brownlee 2018年3月23日 凌晨6:07 #

      不需要模型,使用每个系数对数据输入进行加权,加权和就是预测结果。

  37. Vincent 2018年4月10日 上午10:25 #

    大家好,
    我正在使用 scikit 0.19.1
    我使用随机森林生成了一个训练模型并保存了该模型。这些操作是在 ubuntu 16.01 x86_64 上完成的。
    我将模型复制到一台 windows 10 64 位机器上,并希望重用已保存的模型。但遗憾的是,我收到了以下错误:
    回溯(最近一次调用)
    文件“C:\Users\PC\Documents\Vincent\nicholas\feverwizard.py.py”,第19行,在
    rfmodel=joblib.load(modelfile)
    文件“C:\Python27\lib\site-packages\sklearn\externals\joblib\numpy_pickle.py”,第578行,在load中
    obj = _unpickle(fobj, filename, mmap_mode)
    文件“C:\Python27\lib\site-packages\sklearn\externals\joblib\numpy_pickle.py”,第508行,在_unpickle中
    obj = unpickler.load()
    文件“C:\Python27\lib\pickle.py”,第864行,在load中
    dispatchkey
    文件“C:\Python27\lib\pickle.py”,第1139行,在load_reduce中
    value = func(*args)
    文件“sklearn\tree\_tree.pyx”,第601行,在sklearn.tree._tree.Tree.cinit中
    ValueError: 缓冲区dtype不匹配,预期为’SIZE_t’但得到’long long’

    可能发生了什么?是因为从ubuntu切换到windows吗?但是,我能够在ubuntu中重用该模型。

  38. Pramod 2018年4月17日下午9:03 #

    我们可以在32位操作系统上加载在64位系统上训练的模型吗?

    • Jason Brownlee 2018年4月18日上午8:04 #

      我怀疑它能行。试试看。告诉我结果如何。

  39. Arnaud 2018年4月17日下午9:29 #

    亲爱的Jason

    感谢您提供非常全面的“课程”。

    我有一个可能棘手但“可能非常有用”的问题,关于我新创建的标准Python对象。

    是否有可能在Fortran程序中集成对我的Python对象的调用?

    基本上,我有一个确定性模型,我想在每个时间步递归调用我的Python对象。

    我需要一些特定的库吗?

    谢谢你
    此致

    • Jason Brownlee 2018年4月18日上午8:06 #

      不客气。

      我怀疑这是可能的。归根结底,它们都只是代码。你可能需要某种Python-FORTRAN桥接软件。我没做过这个,抱歉。

  40. Pratip 2018年4月23日下午4:32 #

    你好,先生,
    我想知道是否可以将scikit预加载的数据集与一些新数据集结合起来,以获得更多的训练数据,从而获得更高的准确性,或者首先在scikit加载的数据集上运行,然后使用pickle保存模型并在另一个数据集上运行。
    哪种方法是正确的?
    请帮忙。

    • Jason Brownlee 2018年4月24日上午6:20 #

      当然可以,但这只有在数据以相同方式从相同领域收集的情况下才有意义。

      • swati kumari 2019年4月12日下午5:07 #

        这怎么能做到?当我加载pickle并尝试拟合新数据时,模型只拟合新数据。

        • Jason Brownlee 2019年4月13日上午6:24 #

          如果模型已经拟合、保存、加载,然后在新数据上训练,那么它正在被更新,而不是从头开始训练。

          也许我不明白你遇到的问题?

  41. Ishit Gandhi 2018年5月4日下午6:00 #

    你好,杰森,

    你能举例说明如何存储和加载Pipeline模型吗?

    例如。

    clf = Pipeline([("rbm",rbm),("logistic",logistic)])
    clf.fit(trainX,trainY)

  42. Akash 2018年5月14日下午4:15 #

    你好 jason,
    我叫Akash Joshi。我正在尝试用101000张图像训练我的scikit svm模型,但内存不足。有没有办法可以分小批量训练svm模型?我们可以使用pickle吗?

    • Jason Brownlee 2018年5月15日上午7:51 #

      也许尝试在具有更多RAM的机器上运行,例如EC2实例?

      也许尝试使用数据集的样本?

      也许使用生成器逐步加载数据?

  43. Samarth 2018年5月14日下午4:54 #

    嗨 Jason

    我想知道如何保存minmax转换?有办法保存最终模型,但如何保存转换?

    谢谢

    • Jason Brownlee 2018年5月15日上午7:51 #

      保存每个变量的最小值和最大值。

      或者保存整个对象。

  44. SOORAJ T S 2018年5月16日上午12:30 #

    感谢您的帖子,它信息量很大,但我对数据集的标签或名称有疑问,可以指定每个。

  45. SOORAJ T S 2018年5月16日下午4:11 #

    names = [‘preg’, ‘plas’, ‘pres’, ‘skin’, ‘test’, ‘mass’, ‘pedi’, ‘age’, ‘class’]

    在上面的代码中,“preg”、“plas”、“pres”等是什么意思?

  46. Aniko 2018年6月7日上午12:13 #

    嗨,Jason!

    我创建了一个机器学习(GBM)模型来预测房价,并创建了一个Django应用程序以供使用。该模型有1000多个n_estimators,在每次请求中获得预测之前,加载需要超过1分钟。
    我想只加载joblib转储文件一次,并将模型存储在内存中,避免在每次get请求中加载模型。

    对此您有什么最佳实践?

    谢谢

    • Jason Brownlee 2018年6月7日上午6:31 #

      这听起来更像是一个网络应用软件工程问题,而不是一个机器学习问题。

      也许您可以将模型托管在Web服务之后?

      • Aniko 2018年6月7日下午6:51 #

        谢谢,与此同时,我在Django文档中找到了一些与缓存相关的解决方案,这可能解决了加载问题

  47. LamaOS223 2018年6月9日下午2:00 #

    好的,如果我有2个数据集,例如贷款数据集
    第一个数据集有一个Loan_Status属性
    而第二个没有Loan_Status属性
    如果我在第一个数据集上训练了模型,并且我想预测第二个数据集的Loan_Status,如何做到这一点?请为我这个初学者简化一下

  48. Imti 2018年7月12日下午4:55 #

    嘿Jason,我正在开发一个模型来分类文本文件。我正在按顺序使用CountVectorizer、TfidfTransformer和SGDClassifier在一组数据文件上。我通过您在本文中提到的joblib.dump方法保存了SGDClassifier对象。

    我还需要保存矢量化器和转换器对象/模型吗?因为当我获取一个新文件进行分类时,我将需要再次执行这些步骤。

    • Jason Brownlee 2018年7月13日上午7:33 #

      是的,在模型使用之前,它们需要准备任何数据。

  49. Dennis Faucher 2018年7月28日上午2:38 #

    正是我今天需要的。谢谢你。

  50. Tejaswini 2018年7月30日上午9:01 #

    嗨,Jason,
    感谢这篇文章。当我保存模型并在不同的页面中加载它时,它显示了不同的准确性。

    尝试解决的问题:我正在使用oneclasssvm模型并检测句子中的异常值。

    • Jason Brownlee 2018年7月30日下午2:15 #

      我没见过这种情况,你确定你在完全相同的数据上评估模型吗?

  51. Tejaswini 2018年8月2日下午2:10 #

    是的,Jason,我正在使用gensim word2vec将文本转换为特征向量,然后执行分类任务。保存模型并在另一个会话中重新加载后,它给出了不同的结果。

    • Jason Brownlee 2018年8月2日下午2:11 #

      这很奇怪。我从未见过这种情况。

      也许报告一个故障/bug?

  52. EvapStudent 2018年8月7日上午1:36 #

    嗨,Jason,

    我正在使用MLPRegressor训练神经网络,试图预测不同热交换器几何结构中的压降。我想我已经很好地训练了网络,MRE很低,但我不知道如何使用这个网络。当我尝试使用pickle加载并再次调用时,我在使用“score”时遇到了错误。我是python新手,所以不确定如何为网络引入新数据进行预测或如何概括地进行预测。

    • Jason Brownlee 2018年8月7日上午6:28 #

      我不推荐使用pickle。我推荐使用Keras API保存/加载您的模型。

      一旦你找到了适用于你问题的配置,也许可以直接从sklearn封装器切换到Keras API。

      • EvapStudent 2018年8月7日下午11:13 #

        嗨,Jason,

        感谢您的推荐。有没有简单的方法来保存模型并从中调用以在scikit learn中使用?我在那里制作的模型取得了不错的结果,我只是不知道如何使其达到我实际可以使用网络的程度(即输入几何图形并获得其预测)。

        如果使用Keras API保存/加载是最佳选择,我该如何操作?

  53. Golnoush 2018年8月21日上午1:38 #

    你好 Jason,

    感谢您精彩的教程!pickle.dump(model, open(filename, 'wb')) 只保存神经网络模型还是也保存模型的参数和权重?
    当我们使用pickle.load时,是否会再次进行反向传播和训练?
    我想做的是,我想在训练期间保存整个模型以及权重和参数,并为我拥有的每个测试数据使用相同的训练模型。如果您能在这方面协助我,我将不胜感激。

    • Jason Brownlee 2018年8月21日上午6:19 #

      我相信你不能用pickle来处理神经网络模型——例如Keras模型。

  54. Somo 2018年8月29日下午3:05 #

    嗨,Jason,

    我正在尝试使用joblib.dump(model, 'model.pkl') 保存我的模型,然后在另一个.py文件中重新加载模型 = joblib.load('model.pkl'),但准确性下降了,每次运行结果都大相径庭。我的系数和截距对于这两个模型都是相同的。您知道这可能是什么原因吗?提前感谢。

  55. Dhrumil 2018年9月1日下午3:11 #

    嘿,伙计,我正面临pickle的麻烦,当我尝试加载我的.pkl模型时,我收到了以下错误

    UnicodeDecodeError: 'ascii' codec can't decode byte 0xbe in position 3: ordinal not in range(128)

    你能告诉我一些事情吗,因为我已经尝试了我能找到的所有修复方法。

  56. Aakash Aggarwal 2018年9月8日上午4:57 #

    我想开发一个模型,训练并保存到pickle文件中。从下次开始,当我想训练模型时,它应该以追加模式保存到以前创建的pickle文件中,从而减少训练模型的时间。我正在使用LogisticRegression模型。

    任何帮助都将不胜感激。

  57. My3 2018年10月15日下午10:11 #

    嗨,Jason,

    我有一些将Python代码与Java集成起来的需求。

    我有一个经过训练并保存为pickle文件的ML模型,Randomforestclassifier.pkl。我想使用Java一次性加载它,然后执行我用Python编写的“预测”部分代码。所以我的工作流程是这样的:

    1. 读取Randomforestclassifier.pkl文件(一次性)
    2. 将此模型作为输入发送给“python_file.py”中定义的函数,该函数将从Java为每个请求执行
    3. python_file.py包含预测代码,并且返回的预测应该由Java代码捕获
    请为我的这个工作流程需求提供建议。我已经在Java中使用了processbuilder来执行python_file.py,除了模型一次性加载之外,一切都运行良好。

    您能帮助我实现不使用REST API进行一次性模型加载的客户端服务器Python编程吗?

    • Jason Brownlee 2018年10月16日上午6:37 #

      我建议将其视为任何其他工程项目,收集需求,审查选项,最小化风险。

    • Rahul 2018年10月18日下午6:10 #

      嗨Jason,My3,

      我有一个类似的需求,需要将java与python集成,因为我的模型是用python编写的,在我的项目中我们正在使用java。

      您能在这里提供帮助吗?

  58. Theekshana 2018年10月30日上午12:35 #

    嗨,Jason,

    我训练了我的模型并使用交叉验证分数评估了准确性。

    评估模型后,我应该用整个数据集训练我的模型,然后保存新训练的模型以用于未来的新数据吗?(假设新模型表现良好,准确性接近交叉验证的平均准确性)

    感谢您的教程和对问题的即时回复。🙂

  59. Gagan 2018年12月11日下午5:56 #

    Jason,非常感谢您的贡献。

  60. Roger 2019年1月1日上午5:55 #

    这对我帮助很大。谢谢你

  61. Kiril Kirov 2019年1月4日上午3:19 #

    您将如何保存和加载使用FunctionTransformer创建的自定义函数的scikit-learn管道?

  62. Shubham 2019年1月4日上午8:37 #

    嗨,Jason,

    我有一个非常基本的问题,假设我有一个在2017-2018年训练的模型,6个月后我觉得需要用新数据重新训练它。这里重新训练实际意味着什么,我需要为我的新数据设定目标,并且需要从头开始训练新的时间段吗,我显然没有目标,那么模型如何从新数据中学习呢?

    • Jason Brownlee 2019年1月4日上午11:01 #

      您有很多选择,例如开发新模型、更新旧模型,或将两者与集成模型结合。

  63. Rajesh Mahajan 2019年1月18日上午7:44 #

    嗨,Jason,

    我是新手…所以请原谅,如果我问了什么不正确的问题…

    我有两个阶段。构建模型和预测。

    对于构建模型
    我正在使用vectorizer.fit_transform(data)构建逻辑模型。我的数据是一堆评论,目标是一组类别。为了使用该模型预测新评论的类别,我正在使用在模型构建期间创建的矢量进行预测

    所以,当我执行保存模型 joblib.dump(log_model, "model.sav")时

    用于预测
    当我在稍后的时间点尝试重新运行模型(已保存)时,我不再拥有原始数据集的原始矢量化器了

    log_model = joblib.load("model.sav")
    inputfeatures_nd = vectorizer.transform(newComment);
    pred = log_model.predict(inputfeatures_nd)

    我收到了这个错误 – sklearn.exceptions.NotFittedError: CountVectorizer – Vocabulary wasn't fitted。

    您建议我应该怎么做?我应该将矢量也序列化并存储吗?

    • Jason Brownlee 2019年1月18日上午10:15 #

      您必须使用训练模型时使用的相同矢量化器。将其与您的模型一起保存。

      • Rajesh Mahajan 2019年1月18日下午1:17 #

        谢谢Jason!是的,我保存并重新加载后它就成功了。

  64. Ahmed Sahlol 2019年2月13日下午8:23 #

    谢谢Jason,您的主题很有趣。
    在我的数据集上训练和测试VGG16模型后,当我应用这两种方法时,出现了这个错误(无法pickle _thread.RLock对象)。我还读到Keras模型不可pickle。那么,您认为这些方法适用于我的情况吗?

  65. shashank 2019年2月15日上午12:24 #

    很棒的帖子!继续努力,兄弟!

  66. Nick 2019年2月19日上午2:31 #

    嗨Jason,您承诺的“免费”书籍从未寄到,看起来您正在收集电子邮件以进行促销🙂

  67. mayank 2019年3月6日 早上7:31 #

    嗨 Jason,我有一个 .sav 文件,我的随机森林模型已经在此文件中训练完成。我需要从该 .sav 文件中找回整个用于训练模型的 Python 脚本。这可能吗?

    • Jason Brownlee 2019年3月6日 早上8:02 #

      您可以加载已保存的模型并开始使用它。

  68. Rimsha 2019年3月29日 早上5:05 #

    嗨 Jason,我已经通过一个 .csv 格式的训练数据集文件训练了一个 Naved Baise 的情感分析模型,现在我想用这个模型来检查同样保存在另一个 .csv 文件中的句子的情感,我该如何使用呢?

    • Jason Brownlee 2019年3月29日 早上8:44 #

      保存模型,然后在一个新示例中加载它并进行预测。

  69. Nisha 2019年3月29日 晚上11:23 #

    嗨,Jason,

    我定义了一个 Keras 中的 Class Layer 来执行一些功能。我训练了模型并将其 pickled。现在当我尝试 unpickle 它时,我看到一个错误,显示“未知层 Layer”。
    在这种情况下,我应该如何 pickle 模型?

  70. Sevval 2019年5月8日 下午5:56 #

    我可以使用我之前保存的模型进行预测吗?

  71. Sara 2019年5月13日 下午1:37 #

    当您在这篇文章中说
    “您可能会手动输出您学习到的模型的参数,以便可以直接在 scikit-learn 中使用它们”,
    我看到我们可以手动获取调整后的超参数,例如在 SVM 中,我们可以获取权重系数 (coef_),
    但是,是否可以获取 SVM 超平面参数 w 和 b (y=wx+b) 用于未来的预测?
    我相信 pickle 会保存和加载学习到的模型,包括 w 和 b,但是有没有办法我们可以手动输出 w 和 b,并在 scikit learn 中查看它们是什么?
    非常感谢

    • Jason Brownlee 2019年5月13日 下午2:33 #

      我相信它们可以在 SVM 类中作为属性访问。

      您可能需要仔细查看 API 甚至源代码,以找出系数以及 sklearn 如何专门使用它们进行预测。

      感谢开源,一切都在那里等着我们!

  72. Samuel 2019年5月18日 早上2:55 #

    嗨,感谢这篇有用的文章。我是一个初学者,我需要做文档分类。在我的模型中,我使用

    training_pipeline_data = [
    (‘vectorizer’, _create_vectorizer(lang)),
    (‘densifier’, _create_densifier()),
    (‘scaler’, _create_scaler()),
    (‘classifier’, _create_classifier())
    ]
    training_pipeline = ibpip.Pipeline(training_pipeline_data)
    training_pipeline.fit(features, labels)

    def _create_vectorizer(language)
    stop_words = safe_get_stop_words(language) if language != ‘en’ else ‘english’
    return TfidfVectorizer(sublinear_tf=True, min_df=7, norm=’l2′, ngram_range=(1, 2),
    encoding=’latin-1′, max_features=500, analyzer=’word’,
    stop_words=stop_words)

    def _create_densifier()
    return FunctionTransformer(lambda x: x.todense(), accept_sparse=True, validate=False)

    def _create_scaler()
    return StandardScaler()

    def _create_classifier()
    return GradientBoostingClassifier(n_estimators=160, max_depth=8, random_state=0)

    我需要将整个管道还是仅仅是分类器保存到 pickle 文件中?

    当我保存整个管道时,pickle 文件的大小会随着训练数据的量而增加,但我认为这不应该影响模型大小(只有模型的参数应该影响其大小)

    • Jason Brownlee 2019年5月18日 早上7:40 #

      将所有内容都 pickle 起来。

      是的,您正在保存单词到数字的映射,它包括未来编码新样本所需的整个已知词汇。

  73. Krtin Ahuja 2019年6月17日 晚上9:54 #

    嗨,Jason,
    我如何加载模型以进行进一步预测?

    • Jason Brownlee 2019年6月18日 早上6:39 #

      我在上面的教程中展示了如何加载模型。

      你到底遇到了什么问题?

  74. Raphael 2019年6月21日 晚上8:00 #

    嗨,您的教程的忠实粉丝。
    您对 ONNX (https://onnx.org.cn/) 有何看法?
    您考虑过制作一个教程来解释它是如何工作以及如何使用它吗?

  75. Constantine 2019年6月24日 早上1:43 #

    嗨,感谢您一如既往地提供非常有用的帖子!

    我想问您,这个过程也适用于保存网格搜索模型吗?因为当我尝试保存 grid-search.best_estimator_ 时,它没有给我预期的结果(即我在样本数据上使用相同的分数),而且我找到的解决方案也不起作用。关于如何做到这一点有什么建议吗?

    非常感谢!

    • Jason Brownlee 2019年6月24日 早上6:35 #

      通常我们丢弃网格搜索模型,因为我们只对配置感兴趣,这样我们就可以拟合一个新的最终模型。

  76. Constantine 2019年6月24日 下午5:26 #

    您能否给我指出一个用代码展示如何完成此操作的来源?我已经尝试了(通过我的搜索)以下内容,但它没有给我预期的结果

    grid_elastic = GridSearchCV(elastic, param_grid_elastic,
    cv=tscv.split(X),scoring=’neg_mean_absolute_error’, verbose=1)
    grid_elastic.fit(X,y)
    print(grid_elastic.score(X,y))
    filename = ‘finalized_model_grid.sav’
    joblib.dump(grid_elastic.best_params_, filename,compress=1)
    loaded_params_grid = joblib.load(filename)
    elastic = ElNet().set_params(**loaded_params_grid)
    elastic.fit(X,y)
    result = elastic.score(X, y)
    print(result)

    我对一个示例模型进行网格搜索,拟合它,计算一个用于比较的示例指标,然后尝试保存参数并使用它们稍后实例化最佳估计器,以避免重复进行详尽搜索。但它没有给我相同的结果。出了什么问题?我尝试过只保存 best_estimator_,但它给我相同的错误结果。

  77. ishrat 2019年7月3日 晚上9:59 #

    首先,感谢您一直分享如此精彩的信息。
    这是我的代码

    import time
    import numpy as np
    import pandas as pd
    from nltk import word_tokenize
    from nltk import pos_tag
    from nltk.corpus import stopwords
    from nltk.stem import WordNetLemmatizer
    from sklearn.preprocessing import LabelEncoder
    from collections import defaultdict
    from nltk.corpus import wordnet as wn
    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn import model_selection, svm
    from sklearn.metrics import accuracy_score
    from sklearn.ensemble import RandomForestClassifier
    import pickle

    start_time = time.time()
    np.random.seed(500)

    #仅获取所需的列和行
    dataset = pd.read_csv(“records.csv”, sep=”\t”)
    dataset_new = dataset.iloc[:, [4, 5, 6, 8, 9]]

    df = dataset_new.dropna(subset=[‘Debit’])
    df_required = df.iloc[:, [0, 2]]
    df_required = df_required[df_required[‘Description’] != ‘OPENING BALANCE’]
    df_less = df_required.iloc[:,:]
    df_less = df_less.reset_index(drop=True)

    # 数据集清理
    df_less = df_less.dropna(subset=[‘Description’])
    df_less = df_less.dropna(subset=[‘First Level Category’])
    df_less[‘description’] = ” ”

    for index, row in df_less.iterrows()
    row[‘description’] = row[‘Description’].replace(“-“, ” “)
    row[‘description’] = row[‘description’].replace(“/”, ” “)
    row[‘description’] = row[‘description’].replace(“_”, ” “)
    row[‘description’] = row[‘description’].replace(“:”, ” “)
    row[‘description’] = row[‘description’].replace(“.”, ” “)

    dataset_time = time.time()
    print (“创建数据集耗时 : “, dataset_time – start_time)

    df_less[‘description’] = [entry.lower() for entry in df_less[‘description’]]
    df_less[‘description’] = [word_tokenize(entry) for entry in df_less[‘description’]]
    df_less = df_less.reset_index(drop=True)

    tokenize_time = time.time()
    print (“标记数据集耗时 : “, tokenize_time – dataset_time)

    for index, entry in enumerate(df_less[‘description’])
    Final_words = []
    for word in entry
    if word.isalpha()
    Final_words.append(word)
    df_less.loc[index, ‘desc_final’] = str(Final_words)

    df_others = df_less[df_less[‘desc_final’] == ‘[]’]
    df_less_final = pd.DataFrame()
    df_less_final = df_less[df_less[‘desc_final’] != ‘[]’]
    df_less_final = df_less_final.reset_index(drop=True)
    data_cleanup_time = time.time()
    print (“数据清理耗时”, data_cleanup_time – tokenize_time)

    Train_X, Test_X, Train_Y, Test_Y = model_selection.train_test_split(df_less_final[‘desc_final’],
    df_less_final[‘First Level Category’], test_size=0.33,
    random_state=10,shuffle=True)

    Tfidf_vect = TfidfVectorizer(max_features=106481)
    Tfidf_vect.fit(df_less[‘desc_final’])
    Train_X_Tfidf = Tfidf_vect.transform(Train_X)
    Test_X_Tfidf = Tfidf_vect.transform(Test_X)

    clf = RandomForestClassifier(n_jobs=8, random_state=10)

    clf.fit(Train_X_Tfidf, Train_Y)
    RandomForestClassifier(bootstrap=True, class_weight=None, criterion=’gini’,
    max_depth=None, max_features=’auto’, max_leaf_nodes=None,
    min_impurity_split=1e-07, min_samples_leaf=20,
    min_samples_split=2, min_weight_fraction_leaf=0.0,
    n_estimators=100, n_jobs=8, oob_score=False, random_state=10,
    verbose=0, warm_start=False)
    preds = clf.predict(Test_X_Tfidf)
    print(“随机森林准确率得分 -> “, accuracy_score(preds, Test_Y) * 100)
    preds.tofile(“foo.csv”, sep = ‘\n’)
    dff = pd.DataFrame()
    col_name = [‘category’]
    dff = pd.read_csv(“foo.csv”, names = col_name, sep=”\n”)

    先生,这是一个我已经准备好的模型,现在我想用 pickle 来dump它,但我不知道该怎么做……因为每次我想预测新记录时,我都想像上面那样预处理我的一行,并且也使用了 vectorizer……然后预测结果……您能帮我解决这个问题吗?
    谢谢你

  78. teimoor 2019年7月17日 早上4:14 #

    嗨,我如何快速学习Python以用于深度学习模型,比如LSTM?
    请在Gmail上通知我

  79. Raghad 2019年7月22日 下午5:59 #

    非常感谢您的所有努力,但我是一名机器学习和 Python 的初学者,我有一个基本的概念性问题。
    我使用一个 CSV 文件来训练、测试和拟合我的随机森林模型,然后我将模型保存到一个 pickle 文件中。现在我的合作伙伴想使用该模型对新的未见过的数据(由用户输入)进行预测,所以我的问题是,我应该只发送给她我保存在 pickle 文件中的模型,还是也发送给她我用于训练和拟合模型的数据?我的意思是,即使包含用于拟合模型的数据的 CSV 文件不在同一个文件夹或主机中,pkl 模型也能工作吗?我希望我的问题清楚。再次非常感谢!

    • Jason Brownlee 2019年7月23日 早上7:57 #

      只需要模型即可。

      • Chandan Kumar Jha 2019年8月20日 早上3:05 #

        先生,模型保存和重复使用是没问题的,但是对于像 LabelEncoder 或 StandardScalar 函数这样用于转换特征的预处理步骤怎么办?

        我们需要对未见过的数据集应用相同的转换,那么我们该如何处理呢?我们如何保存这些预处理步骤。

        • Jason Brownlee 2019年8月20日 早上6:28 #

          是的,预处理必须相同。您可能需要保存相关对象。

  80. Fathima 2019年8月31日 早上2:35 #

    我用 python 3.7 训练了模型,我能用 python 3.5 测试它吗?

  81. Ned H 2019年9月8日 晚上11:43 #

    嗨,Jason,

    我是您的博客的忠实粉丝。问题是,虽然保存模型很有用,但模型通常已经是管道的一部分。我成功地使用 joblib 方法存储了预训练的管道,然后将其加载到我构建它的同一环境中并获得预测。但是,当我在 AWS 中保存管道然后将其加载到本地时,我会收到错误。

    在保存管道与原始模型方面,是否有最佳实践?

    也许一个教程,您使用 RandomizedSearchCV 训练管道然后保存它会很有用?

    感谢您所有精彩的教程!

    • Jason Brownlee 2019年9月9日 早上5:16 #

      您会遇到什么错误?

      据我所知,保存/加载管道与保存/加载单个模型相同。

  82. Alban 2019年10月2日 早上1:48 #

    嗨 Jason,感谢您的时间,以及非常有趣的教程!
    我训练并保存了一个随机森林模型,并分析了不同阈值下的分类性能。
    现在我想将这个已保存的随机森林应用于一个新的数据集,以获取预测,但使用与 50% 不同的阈值。但我似乎无法获得 rf.predict_proba(x) 函数的结果,我得到了一个“NotFittedError”……它说我的 rf 模型尚未拟合……我现在很迷茫……我的推理有问题吗?有没有其他方法可以获得分类概率?谢谢。

    • Jason Brownlee 2019年10月2日 早上8:02 #

      也许确认模型已拟合,并且拟合的模型已保存?

  83. Rahel 2019年10月16日 下午6:00 #

    嗨 Jason……代码第13行有错误……不应该是“# Fit the model on 33%”,而应该是“# Fit the model on 67%”,因为我们正在将模型拟合到训练集,即67%……

  84. Shiva Vutukuri 2019年11月6日 早上3:55 #

    嗨,Jason,
    我正在进行 APS 故障斯堪尼亚卡车项目……

    在使用 joblib 库保存和加载文件后,我得到了以下结果

    # 保存模型以备后用
    modelName = ‘finalModel_BinaryClass.sav’
    joblib.dump(finalModel, modelName)
    输出:[‘finalModel_BinaryClass.sav’]

    # 从磁盘加载模型
    loaded_model = joblib.load(modelName)
    result = loaded_model.score(X_validation, Y_validation)
    print(result)
    输出:0.9894375

    我的问题是我找不到最终模型保存的位置……您能帮我一下吗?

    • Jason Brownlee 2019年11月6日 早上6:45 #

      它将位于您的当前工作目录中,例如,您运行代码的位置。

  85. Shiva Vutukuri 2019年11月6日 晚上8:18 #

    非常感谢 Jason 先生

  86. KK 2019年12月9日 下午3:44 #

    先生,您好,

    出色的教程。

    您能告诉我,为什么您使用 .sav 格式保存模型吗?

    我们可以使用 .pkl 格式代替吗?.sav 与 .pkl 或其他格式相比有什么优势?

    谢谢你,
    KK

    • Jason Brownlee 2019年12月10日 早上7:25 #

      我们在本教程中使用 pickle 格式。您可以使用任何您喜欢的文件扩展名。

  87. pat c 2019年12月13日 早上9:47 #

    如果您使用类权重构建模型,在对新数据集进行评分时是否需要以任何方式考虑这一点?

    • Jason Brownlee 2019年12月13日 下午1:41 #

      不,但您应该选择一个最能捕捉预测重要性的指标。

      例如,使用 F-measure 或 G-mean,或精度、ROC AUC 等。

  88. vikash 2019年12月30日 早上12:40 #

    你好,
    我还对训练和测试数据集使用了标准化。我已经部署了模型文件。
    我如何通过 API 调用模型时进行标准化?

  89. SHubham 2020年1月9日 下午4:30 #

    嗨,Jason,

    您能告诉我如何将 .pkl 文件转换为 .pb 文件或 .tflite 文件吗?

    • Jason Brownlee 2020年1月10日 早上7:23 #

      我暂时不知道,也许可以尝试在 stackoverflow 上发帖?

    • Matt 2021年1月21日 早上8:52 #

      SHubham,你找到解决方案了吗?

  90. Murat Kulustepe 2020年1月13日 早上1:55 #

    嗨,Jason!

    我的模型是用excel文件创建的……总之模型已经准备好了。现在我想在线使用模型。我的意思是输入将来自sql数据库,同时我想从模型中看到结果。(预测值)

    您能解释一下该怎么做吗?

    • Jason Brownlee 2020年1月13日 早上8:28 #

      是的,在代码中实现您的模型,然后一次将一行传递给您的模型进行预测。

      • Murat Kulustepe 2020年1月13日 早上9:16 #

        好的,但是怎么做呢?我问是因为我不确定怎么做?
        如果您能稍作解释,或者您能给我一个例子(示例链接),我会很高兴!

        非常感谢。

        • Jason Brownlee 2020年1月13日 下午1:42 #

          我不知道如何回答您——这个问题太宽泛了。您对如何编写自己的算法并保存它拥有完全的自由。

          也许您可以缩小您的问题范围。另外,我没有能力为您实现您的算法。

          如果您更喜欢使用库,上面教程中的示例将是一个很好的起点。

  91. josheeg 2020年1月20日 早上1:24 #

    这些模型文件 pickle 可以用其他任何东西打开或创建吗?
    我知道 Orange 使用一些 scikit learn 并运行了两者。
    但我从未创建过 scikit learn 的 pickle 文件并在 Orange 中打开它,也从未创建过 Orange 的保存模型小部件文件,它是一个 pickle 文件。
    我想用它在 Keras TensorFlow 中打开一个模型,并能够运行应用程序使其与 TensorFlow Lite 兼容,然后在微控制器中运行它。比如树莓派 4,或者可能的要求是它必须运行 Python 3,有些 ARM 处理器可以做到这一点。

  92. Pierre 2020年1月20日 早上6:46 #

    嗨 Jason,我正在通过您的 ML Master w/ Python 书籍学习这个,遇到了这个错误

    回溯(最近一次调用)
    文件 “/Users/pierrenoujeim/Desktop/MLDS/Python/MasterML/ml w: python/code/17. Save and Load Models/pickletest.py”,第 2 行,在
    import pandas
    文件 “/anaconda3/lib/python3.6/site-packages/pandas/__init__.py”,第 19 行,在
    “缺少所需的依赖项 {0}”。format(missing_dependencies))
    ImportError:缺少所需的依赖项 [‘numpy’]

    我原样复制了此页面上的代码,并得到了相同的错误。我该怎么做?

  93. Manuel 2020年1月20日 下午12:52 #

    Jason 一个问题……我们如何将模型结果导出到 Excel 或 ASCII 文件?

    谢谢

  94. Madan Kumar Y 2020年1月28日 下午5:35 #

    嗨,Jason,
    拟合模型后,我如何解封可学习参数(权重和偏差)?我很难从 pickle 文件中获取可学习参数。有什么办法吗?
    谢谢

    • Jason Brownlee 2020年1月29日 早上6:30 #

      每个模型存储其内部参数的方式都不同。

      sckit-learn API 解释了如何访问每个模型的参数,一旦加载。

  95. hayder 2020年2月12日 晚上9:15 #

    我如何将一个类 SVM 的输出存储到 Python 中的缓冲区?

  96. Jose Q 2020年3月22日 下午1:59 #

    嗨,Jason!

    感谢您的本教程!您总是把概念解释得如此简单!

    我有一个问题。

    如果我必须在训练期间使用标量,例如

    X_scaled = scaler.fit_transform(X)

    然后我拟合模型并用 pickle.dump(clf, open(filename, ‘wb’)) 保存它

    那么我猜我必须使用训练期间拟合的相同标量来缩放测试数据进行预测,例如 scaler.transform(x_test)

    我的问题是:除了保存模型之外,我们是否必须保存像示例中的缩放器这样的对象以提供一致性?我们可以使用pickle或joblib吗?

    谢谢你

  97. Jose Q 2020年3月23日上午7:17 #

    谢谢!你太棒了!

  98. Akilu Rilwan 2020年3月24日下午11:21 #

    嗨,Jason,

    感谢您在这里提供的所有内容。我总是觉得您的资源非常有用。

    非常感谢。

  99. Adarsh 2020年4月11日上午12:56 #

    嗨,Jason,
    我正在使用Django将我的模型部署到Web......我的模型的labelencoder出现了一个奇怪的行为......您能通过发布一篇文章来帮助我解决这个问题吗?
    如何在django中部署sklearn模型..

    此致,
    Adarsh

    • Jason Brownlee 2020年4月11日上午6:23 #

      不知道,抱歉。也许可以尝试在stackoverflow上发帖。

  100. AnanShekher Srivastava 2020年4月17日下午11:05 #

    谢谢。这篇帖子展示了如何在一次性训练完整个数据集后保存模型。然而,大多数真实世界的数据集都很大,无法一次性训练。我如何在训练每个数据块后保存模型?

    df = pd.read_csv("an.csv", chunksize=6953)
    for chunk in df
    text = chunk['body']
    label = chunk['user_id']

    X_train, X_test, y_train, y_test = train_test_split(text, label, test_size=0.3 )

    text_clf = Pipeline([('vect', TfidfVectorizer()),
    ('tfidf', TfidfTransformer()),
    ('clf', LinearSVC()),
    ])

    text_clf.fit(X_train, y_train)

    # 将模型保存到磁盘
    filename = 'finalized_model.sav'
    joblib.dump(model, filename)

    这样保存只会给我最后一个数据块训练的模型。我想要每个数据块都训练过的模型。有什么帮助吗?

    • Jason Brownlee 2020年4月18日上午5:58 #

      真的,我不同意。

      如果你的数据无法放入内存,也许可以考虑使用像hadoop与mahout这样的框架,通过在线方法来训练模型?

      • AnanShekher Srivastava 2020年4月19日下午6:39 #

        所以你是说那样保存会给我一个基于每个数据块的模型?

        • Jason Brownlee 2020年4月20日上午5:26 #

          不,有一些算法和算法版本支持迭代学习算法——称为在线学习。

  101. Michael Nguyen 2020年4月18日上午2:16 #

    嗨,Jason,

    我忘记了已保存模型的参数。如何从.sav文件中获取模型的参数?

    • Jason Brownlee 2020年4月18日上午6:06 #

      大多数 sklearn 模型将其用于配置实例的参数作为属性存储(我想……)。检查加载对象的内容,或者检查 sklearn api。

  102. Martino Innocenti 2020年5月14日下午7:15 #

    你好,
    可以将sklearn模型转换为tensorflowlite模型(.tflite)吗?
    我需要在安卓上运行SVM模型,这对我来说似乎是最好的解决方案(如果可能的话)
    还有其他解决方案吗?

  103. Martin M. 2020年5月19日下午6:41 #

    很棒的帖子,谢谢!

    我尝试了一下,但是注意到每次我序列化一个模型时,生成的文件都有不同的校验和。有什么办法可以在数据和算法不变的情况下,保持模型文件的完整性吗?

    这是我的测试代码
    import numpy as np
    from sklearn import linear_model
    import joblib
    import hashlib

    # 设置一个固定的种子…​
    np.random.seed(1979)

    # 内部 md5sum 函数
    def md5(fname)
    hash_md5 = hashlib.md5()
    with open(fname, "rb") as f
    for chunk in iter(lambda: f.read(4096), b"")
    hash_md5.update(chunk)
    return hash_md5.hexdigest()

    # 虚拟回归数据
    X = [[0., 0., 0.,1.], [1.,0.,0.,0.], [2.,2.,0.,1.], [2.,5.,1.,0.]]
    Y = [[0.1, -0.2], [0.9, 1.1], [6.2, 5.9], [11.9, 12.3]]

    # 创建模型
    reg = linear_model.LinearRegression()

    # 将模型保存到磁盘以使其持久化
    with open("reg.joblib", "w")
    joblib.dump(reg, "reg.joblib")

    # 从磁盘加载持久化模型
    with open("reg.joblib", "r")
    model = joblib.load("reg.joblib")

    # 拟合与预测
    reg.fit(X,Y)
    model.fit(X,Y)
    myprediction1 = reg.predict([[2., 2., 0.1, 1.1]])
    myprediction2 = model.predict([[2., 2., 0.1, 1.1]])

    # 运行多次…为什么 md5sum 每次都变?
    print(md5("reg.joblib"))
    print(myprediction1, myprediction2)

  104. Saket Nandan 2020年5月30日上午3:21 #

    xgb_clf =xgb.XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
    colsample_bynode=1, colsample_bytree=0.7, gamma=0.0, gpu_id=-1,
    importance_type='gain', interaction_constraints='',
    learning_rate=0.1, max_delta_step=0, max_depth=10,
    min_child_weight=3, monotone_constraints='()',
    n_estimators=100, n_jobs=0, num_parallel_tree=1,
    objective='binary:logistic', random_state=50, reg_alpha=1.2,
    reg_lambda=1.6, scale_pos_weight=1.0, subsample=0.9,
    tree_method='exact', validate_parameters=1, verbosity=None)

    xgb_clf.fit(X1, y1)
    # 预测训练集
    print('train set')
    y2_pred = xgb_clf.predict(X1)
    # 打印准确度
    print(' xtra Gradient boosting Classifier model accuracy score for train set : {0:0.4f}'. format(accuracy_score(y1, y2_pred)))

    我使用XGBoostingClassifier()设计了模型

    然后,

    #pip install pickle-mixin
    import pickle

    # 将模型保存到本地文件系统
    filename = 'finalized_model.pickle'
    pickle.dump(xgb_clf, open(filename, 'wb'))

    当我传入训练数据集来检查我的pickle模型是否工作时?

    # 使用保存的模型进行预测。
    loaded_model = pickle.load(open(filename, 'rb'))
    prediction=loaded_model.predict(X1) #X1是训练集
    print(prediction)

    输出:-[0 0 0 ... 1 1 1]

    它给出了很好的输出

    但是当我给出一个单独的输入列表时,它会报错,例如

    # 使用保存的模型进行预测。
    loaded_model = pickle.load(open(filename, 'rb'))
    prediction=loaded_model.predict([[62.0,9.0,16.0,39.0,35.0,205.0]])
    print(prediction)

    TypeError: 输入数据不能是列表。

    当我删除 [] 括号时,它又会报错,例如

    # 使用保存的模型进行预测。
    loaded_model = pickle.load(open(filename, 'rb'))
    prediction=loaded_model.predict([62.0,9.0,16.0,39.0,35.0,205.0])
    print(prediction)

    TypeError: 输入数据不能是列表。

    当我从输入中删除所有[[]]时

    # 使用保存的模型进行预测。
    loaded_model = pickle.load(open(filename, 'rb'))
    prediction=loaded_model.predict(62.0,9.0,16.0,39.0,35.0,205.0)
    print(prediction)

    TypeError: predict()接受2到6个位置参数,但提供了7个

    拜托,帮我解决这个问题

  105. jorge Eliecer 2020年6月14日下午11:18 #

    Jason
    优秀的文章和解释方式。示例运行正确。

  106. Osama 2020年6月28日下午9:48 #

    我能从这个加载的模型中绘制训练与测试的准确率吗?

    • Jason Brownlee 2020年6月29日上午6:34 #

      你可以计算并打印出来,但是你怎么画出来呢?条形图吗?这似乎不足以绘制。

  107. Kahina 2020年8月4日下午11:35 #

    你好,
    我可以使用 joblib 来保存和加载 LSI 模型吗?还是我应该使用另一个模块?

    谢谢

  108. Chamsedine AIDARA 2020年8月8日下午10:30 #

    你好,感谢你的演示
    如何对未见过的数据进行预测

  109. Praveen Kumar M 2020年10月6日上午1:55 #

    你好。感谢这个精彩的教程。它按照这里所说的运行了。

    我有一个疑问。

    我用pickle输出模型后,有可能在R中打开模型吗?

    简单来说,pickle输出(根据教程是二进制输出)可以被R读取吗?

    • Jason Brownlee 2020年10月6日上午6:59 #

      我不知道 pickle 过的 Python 模型是否可以在 R 中使用。R 中可能存在执行此操作的代码,请尝试 Google 搜索。

  110. Nick McElwaine 2020年10月11日上午2:55 #

    我知道你不太喜欢Windows,但我还是坚持使用它。只是想说skikit-learn在Windows上不可用,但你已经教程了一个很好的编码和比较不同算法的例子,所以我没有它也能过。

  111. Sam McDonald 2021年1月27日下午2:58 #

    你可以在序列化的dump文件中保存多个模型吗?

    • Jason Brownlee 2021年1月28日上午5:54 #

      也许可以。

      您可能需要查看 pickle 的文档。

  112. Eli 2021年2月11日上午9:31 #

    非常感谢

  113. Hadis 2021年2月25日上午2:12 #

    我无法打开保存的.npy文件。当我点击文件打开它时,我收到以下文本

    错误!C:\Users\hesab\Desktop\Hadis\PdSM.h5不是UTF-8编码的
    保存已禁用。
    更多详情请查看控制台。

    请帮助..我如何访问保存在此文件中的权重和偏差?

    • Jason Brownlee 2021年2月25日上午5:34 #

      听起来你的电脑有问题。

      也许可以与你的管理员沟通,或者查看你的操作系统的帮助文档。

      • Hadis 2021年2月26日上午9:53 #

        谢谢你的回复。

        即使我换了笔记本电脑,这个问题也没有解决。我无法访问权重和偏差。

        我在想是否还有其他办法来解决这个问题。🙁

  114. Peter 2021年3月21日上午12:51 #

    如何从保存的模型中获取准确度值?

    • Jason Brownlee 2021年3月21日上午6:09 #

      加载模型,在保留的测试集上进行预测,将预测结果与预期值进行比较。

      • Kanda 2021年3月28日下午8:04 #

        如果saved_model的形式是frozen_inference_graph.pb或graph.pbtxt,我们能得到准确度值吗?代码是什么样的?请帮助我。谢谢

  115. Qua552 2021年4月17日上午2:41 #

    嗨,Jason,感谢您的文章。不过有个简短的问题——您提到了
    “手动序列化。您可能希望手动输出已学习模型的参数,以便将来可以直接在 scikit-learn 或其他平台中使用它们。”
    您能告诉我,如果我只有截距和斜率,如何加载模型吗?这应该可以,对吧?它是一个多特征线性回归模型。
    谢谢。

    • Jason Brownlee 2021年4月17日上午6:12 #

      是的,您可以加载系数并实现一个函数,该函数使用这些系数自己进行预测。

  116. Qua552 2021年4月19日上午1:40 #

    好的,那是不是不能直接使用 sklearn.linear_model -> LogisticRegression 对象并为其赋值?(我试过但没成功…)

  117. Ephrem 2021年4月22日上午9:59 #

    感谢这个很棒的教程,我有一个单独的测试数据集,以csv文件形式存在。

    我能知道如何在加载模型后,按照您的教程中解释的那样,对其进行预测吗?

    我是否需要再次将test.csv文件拆分为X_train, X_test, y_train和y_test?

  118. Samira 2021年5月20日下午5:13 #

    感谢这篇有趣的教程。
    当我想用这段代码保存模型时

    # 将模型保存到磁盘
    filename = 'finalized_model.sav'
    pickle.dump(model, open(filename, 'wb'))

    我收到这个错误

    "TypeError: cannot pickle '_thread.RLock' object"

    这意味着我用 pickle 对对象进行 pickle 操作,但再次收到了错误。
    您能告诉我原因吗?

    • Jason Brownlee 2021年5月21日上午5:56 #

      不客气。

      抱歉,我没见过那个错误。也许可以尝试将你的代码和错误发布到 stackoverflow.com

  119. Hansel 2021年7月28日下午2:52 #

    嗨,Jason,我目前正在做我的机器学习项目,手头有很多数据集(CSV文件)。如果我用一个数据集训练一个机器学习模型,并用pickle或joblib保存它,我需要为其余的数据集也这样做吗?(这样我就会有更多保存的模型)还是我可以直接将保存的模型加载到另一个数据集上,让程序处理预测?

    希望我的问题清楚,感谢您的帮助。

    附:你的网站对机器学习的初学者和专家都非常有帮助。

    • Jason Brownlee 2021年7月29日上午5:09 #

      你只需要保存模型,而不是数据集。你可能还需要保存数据预处理对象,或者直接使用管道并保存它。

  120. Marcos 2021年7月31日上午6:28 #

    你好,Jason,很棒的帖子。

    我正在训练一个XGBoost模型,但当我保存它并加载后将模型应用于相同数据时,结果却大相径庭(几乎与保存模型之前用模型预测数据时获得的结果相反)。数据是完全相同的。

    例如,保存模型之前的混淆矩阵可能如下所示
    0/1
    0 80/20
    1 20/80

    而加载模型后相同数据的混淆矩阵是
    0/1
    0 20/80
    1 20/80

    我用你在这篇文章中介绍的不同方法保存了模型,但情况依然存在。问题可能出在哪里?

    谢谢。

  121. Satyajeet Narayan 2021年12月2日下午6:02 #

    嗨,Jason,
    我正在进行文本分类,使用 tfidf 向量化器从文本中创建向量,并使用逻辑回归(不进行超参数调整)进行分类。

    一切正常。预测也没问题。

    但是当我将模型保存为 pickle 或 joblib 并使用它时,它会显示错误,提示

    "X 每个样本有 8 个特征;预期 1424 个"
    我传入的字符串被转换为8个不同的单词,然后进行向量化。但是,当我从头开始运行模型时,相同的字符串不会引发任何错误并被预测。

    此错误仅在模型保存为 pickle 或 joblib 后使用时发生。

    • Adrian Tam
      Adrian Tam 2021年12月8日上午6:21 #

      没有看到你是怎么做的,真的很难说哪里出了问题。你能检查一下你是否真的保存和加载了正确的模型,并且输入完全相同吗?

  122. Manolo 2022年1月27日上午5:11 #

    你好,

    我在训练完成后尝试使用 pickle 和 joblib 保存我的 GridSearchCV 模型。但我总是遇到相同的错误:“cannot pickle 'weakref' object”。几个月前用 pickle 完美地工作,但现在我似乎无法保存模型。

    如果有人能帮助我,我将不胜感激。

    马诺洛

    • James Carmichael 2022年2月5日上午11:07 #

      嗨,Manolo…您能提供确切的错误信息,以便我更好地帮助您吗?

      • Andrea 2022年3月31日下午7:23 #

        嗨。我也有同样的问题。pickle 之前可以工作,但现在它抛出了一个弱引用错误。

        这是完整的错误打印信息

        回溯(最近一次调用)
        文件“/mnt/envs/card_env/lib64/python3.6/site-packages/IPython/core/interactiveshell.py”,第3343行,在run_code中
        exec(code_obj, self.user_global_ns, self.user_ns)
        File “”, line 1, in
        pickle.dump(clf, open(filename, 'wb'))
        TypeError: 无法序列化弱引用对象

        • James Carmichael 2022年4月1日上午9:18 #

          嗨,Andrea……您可能想在Google Colab中尝试您的代码,以确定您的本地安装是否存在问题。

  123. Nelson 2022年4月6日上午2:19 #

    使用“.sav”扩展名有什么理由吗?

  124. Carol Ladino 2022年5月12日上午6:26 #

    你好,Jason。

    我正在尝试使用pickle保存我用scikit learn创建的模型。但是当我尝试调用模型时,我发现它保存为空文件。

    1. 我遇到了那个错误“write() argument must be str, not bytes”,所以我将“wb”改成了“w”。

    再次运行代码,尝试保存模型,但发现下一个错误

    2. “typeerror an integer is required (got type _io.textiowrapper)”
    我不知道你有没有什么建议

    谢谢你

  125. Ved Prakash 2022年7月15日下午9:48 #

    当我运行我的flask API时。我希望它能在整个本地网络中访问。当我尝试 app.run('我的机器IP地址')时,它会抛出错误。可能的原因是什么?

    • James Carmichael 2022年7月16日上午7:10 #

      嗨,Ved……请提供确切的错误信息,以便我们更好地帮助您。

  126. Subra 2022年7月23日上午1:20 #

    你好 Jason,

    感谢您的文章。它们很有帮助

    在序列化训练好的模型之前,对整个数据集的预测变量(X)进行缩放和独热编码,以及对目标变量(y)进行标签编码,这样做可以吗?您上面分享的示例没有执行缩放或编码。所以我很困惑在保存训练好的模型以供以后使用之前,对特征进行缩放和编码是否是好的实践。

    • James Carmichael 2022年7月23日上午12:01 #

      嗨,Subra……我们确实建议您按照您的建议包含缩放和编码。

  127. Rachel 2022年10月15日下午10:17 #

    谢谢你,先生,你很有用

    • James Carmichael 2022年10月16日上午12:59 #

      非常欢迎您,Rachel!我们感谢您的支持和反馈!

  128. Surapureddy Amarnath Reddy 2022年12月7日下午10:52 #

    先生,您好,

    我有一个小而棘手的问题。

    1) 这里是拟合数据并保存模型。


    model = LogisticRegression()
    model.fit(X_train, Y_train)
    # 将模型保存到磁盘
    filename = 'finalized_model.sav'
    joblib.dump(model, filename)

    2) 加载模型并预测测试数据。
    a) 如何知道模型的规模(训练数据集的大小)?
    b) 如何检查 X_train 的大小(从加载模块中)?

  129. Aya 2023年4月8日下午8:12 #

    您好,我在 Kaggle 上使用 joblib 训练并保存了一个模型,模型已成功保存和加载。但是,在下载保存的模型文件以在 anaconda 中使用后,我收到错误“文件无法成功打开”。

  130. Jamie 2024年6月27日上午10:40 #

    您好。我按照您的示例使用 pickle 保存了我的 MLP 模型。然后我打开模型并按照您的另一个示例使用该模型创建了 ROC 曲线,这运行良好。但是,当我尝试使用 .predict 时,没有一个样本被分类为 1;它们都为 0。这不对,因为 AUC 为 0.936,而且我在最初创建模型时使用了相同的数据来测试模型。它是一个非常好的模型,具有高准确度、精确度、召回率、特异性和 F1 分数。您知道为什么 .predict 不适用于 pickled MLP 模型吗?

    • James Carmichael 2024年6月28日上午7:39 #

      嗨 Jamie……听起来当您在 pickled MLP 模型上使用 .predict 方法时,数据预处理或模型加载过程可能存在问题。以下是一些您可以遵循的故障排除步骤来解决此问题

      ### 故障排除步骤

      1. **检查数据预处理:**
      确保您用于预测的数据与用于训练的数据以相同的方式进行预处理。这包括缩放、编码和任何其他转换。

      python
      from sklearn.preprocessing import StandardScaler

      # 假设您在训练期间使用了 StandardScaler 进行预处理
      scaler = StandardScaler()
      X_train_scaled = scaler.fit_transform(X_train)

      # 对新数据使用相同的缩放器
      X_test_scaled = scaler.transform(X_test)

      2. **验证模型加载:**
      确保您正确地从 pickle 文件加载模型。

      python
      import pickle

      with open('mlp_model.pkl', 'rb') as file:
      model = pickle.load(file)

      3. **检查模型的预测阈值:**
      MLP 模型的 .predict 方法通常使用 0.5 的阈值来分类样本。如果预测概率接近阈值,预处理中的细微差异可能会导致所有预测都为 0。

      python
      predictions = model.predict(X_test_scaled)

      要调查此问题,您可以检查预测概率

      python
      predicted_probabilities = model.predict_proba(X_test_scaled)[:, 1]
      print(predicted_probabilities)

      如有必要,您可以手动调整阈值

      python
      threshold = 0.5
      predictions = (predicted_probabilities >= threshold).astype(int)

      4. **与原始评估进行交叉检查:**
      比较原始预测和概率与新预测和概率,以识别差异。

      python
      # 原始预测和概率
      original_predictions = model.predict(X_train_scaled)
      original_probabilities = model.predict_proba(X_train_scaled)[:, 1]

      # 新预测和概率
      new_predictions = model.predict(X_test_scaled)
      new_probabilities = model.predict_proba(X_test_scaled)[:, 1]

      print(original_predictions)
      print(new_predictions)
      print(original_probabilities)
      print(new_probabilities)

      ### 示例工作流程
      这是一个完整的示例,以说明这些步骤

      python
      import pickle
      import numpy as np
      from sklearn.preprocessing import StandardScaler
      from sklearn.neural_network import MLPClassifier
      from sklearn.metrics import roc_curve, auc

      # 加载模型
      with open('mlp_model.pkl', 'rb') as file
      model = pickle.load(file)

      # 假设您有测试数据
      X_test = ... # 您的测试数据
      y_test = ... # 您的测试标签

      # 预处理测试数据
      scaler = StandardScaler()
      X_test_scaled = scaler.fit_transform(X_test)

      # 获取预测
      predicted_probabilities = model.predict_proba(X_test_scaled)[:, 1]
      predictions = (predicted_probabilities >= 0.5).astype(int)

      # 验证 ROC 曲线
      fpr, tpr, thresholds = roc_curve(y_test, predicted_probabilities)
      roc_auc = auc(fpr, tpr)

      print(f"ROC AUC: {roc_auc}")
      print(f"Predictions: {predictions}")

      # 调试输出
      print(f"Predicted probabilities: {predicted_probabilities}")
      print(f"Prediction threshold applied: {0.5}")

      通过遵循这些步骤,您应该能够诊断为什么您的 .predict 方法没有产生预期结果,并确保您的预处理和预测步骤是一致的。

发表评论

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。