【问题标题】:Save PyML.classifiers.multi.OneAgainstRest(SVM()) object?保存 PyML.classifiers.multi.OneAgainstRest(SVM()) 对象?
【发布时间】:2011-02-10 01:47:15
【问题描述】:

我正在使用PYML 构建多类线性支持向量机 (SVM)。在训练 SVM 之后,我希望能够保存分类器,以便在后续运行中我可以立即使用分类器而无需​​重新训练。不幸的是,该分类器没有实现 .save() 函数,并且尝试腌制它(使用标准 pickle 和 cPickle )会产生以下错误消息:

pickle.PicklingError: Can't pickle : it's not found as __builtin__.PySwigObject

有没有人知道解决这个问题的方法或没有这个问题的替代库?谢谢。

编辑/更新
我现在正在训练并尝试使用以下代码保存分类器:

mc = multi.OneAgainstRest(SVM()); mc.train(dataset_pyml,saveSpace=False); 对于 i,枚举中的分类器(mc.classifiers): 文件名=os.path.join(前缀,labels[i]+".svm"); 分类器.保存(文件名);

请注意,我现在使用 PyML 保存机制而不是酸洗进行保存,并且我已将“saveSpace=False”传递给训练函数。但是,我仍然收到错误消息:

ValueError:为了保存数据集,您需要训练为:s.train(data, saveSpace = False)

但是,我传递的是 saveSpace=False... 那么,如何保存分类器?

附言
我正在使用的项目是pyimgattr,以防您想要一个完整的可测试示例...该程序使用“./pyimgattr.py train”运行...这会给您这个错误。另外,关于版本信息的注释:

[michaelsafyan@codemage /Volumes/Storage/classes/cse559/pyimgattr]$ python Python 2.6.1(r261:67515,2010 年 2 月 11 日,00:51:29) [GCC 4.2.1 (Apple Inc. build 5646)] 在达尔文 输入“帮助”、“版权”、“信用”或“许可”以获取更多信息。 >>> 导入 PyML >>> 打印 PyML.__version__ 0.7.0

【问题讨论】:

    标签: python pickle svm libsvm pyml


    【解决方案1】:

    在第 96 行的 multi.py 中,“self.classifiers[i].train(datai)”被调用而不传递“**args”,所以如果你调用“mc.train(data, saveSpace=False)” ,这个 saveSpace-Argument 会丢失。这就是为什么如果您尝试将分类器单独保存在多类分类器中时会收到错误消息的原因。但是,如果您更改此行以传递所有参数,则可以单独保存每个分类器:

    #!/usr/bin/python
    
    import numpy
    
    from PyML.utils import misc
    from PyML.evaluators import assess
    from PyML.classifiers.svm import SVM, loadSVM
    from PyML.containers.labels import oneAgainstRest
    from PyML.classifiers.baseClassifiers import Classifier
    from PyML.containers.vectorDatasets import SparseDataSet
    from PyML.classifiers.composite import CompositeClassifier
    
    class OneAgainstRestFixed(CompositeClassifier) :
    
        '''A one-against-the-rest multi-class classifier'''
    
        def train(self, data, **args) :
            '''train k classifiers'''
    
            Classifier.train(self, data, **args)
    
            numClasses = self.labels.numClasses
            if numClasses <= 2:
                raise ValueError, 'Not a multi class problem'
    
            self.classifiers = [self.classifier.__class__(self.classifier)
                                for i in range(numClasses)]
    
            for i in range(numClasses) :
                # make a copy of the data; this is done in case the classifier modifies the data
                datai = data.__class__(data, deepcopy = self.classifier.deepcopy)
                datai =  oneAgainstRest(datai, data.labels.classLabels[i])
    
                self.classifiers[i].train(datai, **args)
    
            self.log.trainingTime = self.getTrainingTime()
    
        def classify(self, data, i):
    
            r = numpy.zeros(self.labels.numClasses, numpy.float_)
            for j in range(self.labels.numClasses) :
                r[j] = self.classifiers[j].decisionFunc(data, i)
    
            return numpy.argmax(r), numpy.max(r)
    
        def preproject(self, data) :
    
            for i in range(self.labels.numClasses) :
                self.classifiers[i].preproject(data)
    
        test = assess.test
    
    train_data = """
    0 1:1.0 2:0.0 3:0.0 4:0.0
    0 1:0.9 2:0.0 3:0.0 4:0.0
    1 1:0.0 2:1.0 3:0.0 4:0.0
    1 1:0.0 2:0.8 3:0.0 4:0.0
    2 1:0.0 2:0.0 3:1.0 4:0.0
    2 1:0.0 2:0.0 3:0.9 4:0.0
    3 1:0.0 2:0.0 3:0.0 4:1.0
    3 1:0.0 2:0.0 3:0.0 4:0.9
    """
    file("foo_train.data", "w").write(train_data.lstrip())
    
    test_data = """
    0 1:1.1 2:0.0 3:0.0 4:0.0
    1 1:0.0 2:1.2 3:0.0 4:0.0
    2 1:0.0 2:0.0 3:0.6 4:0.0
    3 1:0.0 2:0.0 3:0.0 4:1.4
    """
    file("foo_test.data", "w").write(test_data.lstrip())
    
    train = SparseDataSet("foo_train.data")
    mc = OneAgainstRestFixed(SVM())
    mc.train(train, saveSpace=False)
    
    test = SparseDataSet("foo_test.data")
    print [mc.classify(test, i) for i in range(4)]
    
    for i, classifier in enumerate(mc.classifiers):
        classifier.save("foo.model.%d" % i)
    
    classifiers = []
    for i in range(4):
        classifiers.append(loadSVM("foo.model.%d" % i))
    
    mcnew = OneAgainstRestFixed(SVM())
    mcnew.labels = misc.Container()
    mcnew.labels.addAttributes(test.labels, ['numClasses', 'classLabels'])
    mcnew.classifiers = classifiers
    print [mcnew.classify(test, i) for i in range(4)]
    

    【讨论】:

    • @ephes,对不起,你能澄清一下吗?我应该通过什么来训练; saveSpace=True 还是 saveSpace=False?另外,加载分类器怎么样......如果我按照你的建议单独加载它们,我如何将它们放回单个多类分类器中?
    • saveSpace=False(奇怪的东西......)PyMLs 抽象真的很容易泄漏。好的,我更改了示例源以重新读取模型并构建一个新的多类分类器并重新计算测试数据的分数。
    • 谢谢。看起来您的 OneAgainstRestFixed 与原始 OneAgainstRest 相同,除了您使用“self.classifiers[i].train(datai, **args)”而原始意外省略了“**args”参数。现在事情正在保存,但加载工作不正常。我将为此创建一个后续问题。
    • 你不会碰巧有这个问题的答案吧?:stackoverflow.com/questions/2687981/…
    【解决方案2】:

    获取更新版本的 PyML。从 0.7.4 版开始,可以保存 OneAgainstRest 分类器(使用 .save() 和 .load());在该版本之前,保存/加载分类器非常重要且容易出错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-22
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      相关资源
      最近更新 更多