【问题标题】:Updating Python Pickle Object更新 Python Pickle 对象
【发布时间】:2016-04-23 00:16:17
【问题描述】:

我正在做一个机器学习项目,为此我正在使用 Python 的 pickle 模块。

基本上,我正在解析一个巨大的数据集,这在一次执行中是不可能的,这就是为什么我需要保存分类器对象并在下一次执行中更新它。

所以我的问题是,当我使用新数据集再次运行程序时,已经创建的泡菜对象是否会被修改(或更新)。如果不是,那么每次运行程序时如何更新同一个泡菜对象。

save_classifier = open("naivebayes.pickle","wb")
pickle.dump(classifier,save_classifier)
save_classifier.close()

【问题讨论】:

  • 不会自动发生任何事情。下一次运行程序需要打开文件,将其中的 pickle 加载回一个普通的 Python 对象,修改该对象,然后像上面一样将其保存回来。
  • @KirkStrauser 这就是我要说的。我应该只留下这样的代码吗?为下一次运行。已经创建的 naivebayes.pickle 会更新吗?
  • 分类器是否适合 RAM 而不会影响您的其余计算?
  • @Arqam 文件中的泡菜并没有什么“特别”之处。这只是一个普通的文件。如果您更新classifier,然后再次运行上面的代码,naivebayes.pickle 将保留新版本。但这不会自行发生:在您运行pickle.dump 行之前,您对classifier 的任何修改都不会写入naivebayes.pickle
  • @sobek 我没有立即完成完整的数据集,这就是它能够适应的原因。我正在破坏数据集,然后通过对每个细分数据集进行训练来修改我的分类器对象。

标签: python pickle


【解决方案1】:

取消腌制您的classifier 对象将重新创建它,使其处于腌制时的状态,因此您可以继续使用数据集中的新数据对其进行更新。在程序运行结束时,您再次腌制classifier 并再次将其保存到文件中。最好不要覆盖同一个文件,而是保留一个备份(或者更好的是,一系列备份),以防万一你搞砸了。这样一来,您就可以轻松回到 classifier 的已知良好状态。

您应该尝试酸洗,使用一个简单的程序和一个简单的对象来酸洗和解酸,直到您对这一切的工作原理完全有信心。


这是如何更新腌制的classifier 数据的粗略草图。

import pickle
import os
from os.path import exists
# other imports required for nltk ...

picklename = "naivebayes.pickle"

# stuff to set up featuresets ...

featuresets = [(find_features(rev), category) for (rev, category) in documents]
numtrain = int(len(documents) * 90 / 100)
training_set = featuresets[:numtrain]
testing_set = featuresets[numtrain:]

# Load or create a classifier and apply training set to it
if exists(picklename):
    # Update existing classifier
    with open(picklename, "rb") as f:
        classifier = pickle.load(f)
    classifier.train(training_set)
else:
    # Create a brand new classifier    
    classifier = nltk.NaiveBayesClassifier.train(training_set)

# Create backup
if exists(picklename):
    backupname = picklename + '.bak'
    if exists(backupname):
        os.remove(backupname)
    os.rename(picklename, backupname)

# Save
with open(picklename, "wb") as f:
    pickle.dump(classifier, f)

第一次运行这个程序时,它将创建一个新的classifier,用training_set 中的数据对其进行训练,然后将classifier 腌制为“naivebayes.pickle”。以后每次运行这个程序时,它都会加载旧的classifier 并对其应用更多的训练数据。


顺便说一句,如果您在 Python 2 中执行此操作,您应该使用更快的 cPickle 模块;你可以通过替换来做到这一点

import pickle 

import cPickle as pickle

【讨论】:

  • 所以当我在同一个对象上运行pickle.dump时,之前保存的分类器对象不会被删除,而是会被修改对吧?
  • @Arqam:取决于您在保存分类器时是否指定不同的文件名。每次使用相同的名称,它会在重写文件时有效地删除以前的版本。
  • 当您执行pickle.dump(classifier,save_classifier) 时,它会将当前classifier 对象的腌制表示保存到打开的文件save_classifier,如果该文件已经存在,则覆盖旧内容。这就是为什么我建议将腌制数据保存在一系列文件中。例如naivebayes000.picklenaivebayes001.pickle
  • @PM2Ring 但最终我将不得不使用经过充分训练的一个分类器对象,从而保存在一个文件中进行分类?而马蒂诺所说的,对吗?
  • @PM2Ring 有一次我可以使用一个腌制分类器进行训练,对吗?那么拥有这么多文件有什么帮助呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-17
  • 2019-10-15
相关资源
最近更新 更多