0

我正在使用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... 那么,如何保存分类器?

PS
我正在使用的项目是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
4

2 回答 2

2

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

#!/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)]
于 2010-04-20T17:13:57.493 回答
0

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

于 2010-06-20T06:51:30.013 回答