使用pyBrain _splitWithPortion的AttributeError - 对象类型改变了吗?

时间:2015-01-11 14:03:18

标签: python pybrain

我在基本分类教程here之后测试了pybrain,并使用更实际的数据here对其进行了不同的测试。但是,在应用带有错误的trndata._convertToOneOfMany()时收到此错误:

AttributeError: 'SupervisedDataSet' object has no attribute '_convertToOneOfMany

数据集是作为classification.ClassificationDataSet对象创建的,但是调用splitWithProportion似乎更改了它supervised.SupervisedDataSet对象,所以对于Python来说这个错误并不像看守那样出错.SperpervisedDataSet没有&# 39; t有那个方法,classification.ClassificationDataSet呢。 Code here

然而,在这么多教程中使用相同的确切代码我觉得我必须遗漏一些东西,因为很多其他人都有它工作。我已经看过github上代码库的变化,而且这个功能没有什么,我也试过在Python 3和2.7下运行,但没有区别。如果有人有任何指示让我回到正确的道路上,那将非常感激。

#flatten the 64x64 data in to one dimensional 4096
ds = ClassificationDataSet(4096, 1 , nb_classes=40)
for k in xrange(len(X)): #length of X is 400
    ds.addSample(np.ravel(X[k]),y[k])
    # a new sample consisting of input and target

print(type(ds))      
tstdata, trndata = ds.splitWithProportion( 0.25 )
print(type(trndata))

trndata._convertToOneOfMany()
tstdata._convertToOneOfMany()

6 个答案:

答案 0 :(得分:18)

我遇到了同样的问题。我添加了以下代码,使其在我的机器上运行。

tstdata_temp, trndata_temp = alldata.splitWithProportion(0.25)

tstdata = ClassificationDataSet(2, 1, nb_classes=3)
for n in xrange(0, tstdata_temp.getLength()):
    tstdata.addSample( tstdata_temp.getSample(n)[0], tstdata_temp.getSample(n)[1] )

trndata = ClassificationDataSet(2, 1, nb_classes=3)
for n in xrange(0, trndata_temp.getLength()):
    trndata.addSample( trndata_temp.getSample(n)[0], trndata_temp.getSample(n)[1] )

这会将tstdatatrndata转换回ClassificationDataSet类型。

答案 1 :(得分:3)

let ballcatagery: UInt32 = 0x1 << 0 // Not that you have misspelled word "category", which can lead to errors if you expect somewhere a word "category" instead of your actual "categary". let paddlecategary : UInt32 = 0x1 << 1 的实现在PyBrain版本0.3.2和0.3.3之间发生了变化,引入了破坏多态性的这个bug。
截至目前,图书馆自2015年1月起尚未更新,因此使用某种解决方法是目前唯一的行动方案。

您可以在此处查看责任提交:https://github.com/pybrain/pybrain/commit/2f02b8d9e4e9d6edbc135a355ab387048a00f1af

答案 2 :(得分:1)

我遇到同样的问题,并认为我已经解决了这个问题:请参阅此pull request

(Python 2.7.6,PyBrain 0.3.3,OS X 10.9.5)

答案 3 :(得分:1)

我在Muhammed Miah尝试了建议的解决方法,但在行tutorial处运行时仍然被绊倒了:

print( trndata['input'][0], trndata['target'][0], trndata['class'][0])

trndata [&#39; class&#39;]是一个空数组,因此index [0]引发了错误。

我能够通过创建自己的函数ConvertToOneOfMany来解决方法:

def ConvertToOneOfMany(d,nb_classes,bounds=(0,1)):
  d2 = ClassificationDataSet(d.indim, d.outdim, nb_classes=nb_classes)
  for n in range(d.getLength()):
    d2.addSample( d.getSample(n)[0], d.getSample(n)[1] )
  oldtarg=d.getField('target')
  newtarg=np.zeros([len(d),nb_classes],dtype='Int32')+bounds[0]
  for i in range(len(d)):
    newtarg[i,int(oldtarg[i])]=bounds[1]
  d2.setField('class',oldtarg)
  d2.setField('target',newtarg)
  return(d2)

答案 4 :(得分:0)

所以,我做了以下操作而没有收到错误:

from pybrain.datasets import ClassificationDataSet
ds = ClassificationDataSet(4096, 1 , nb_classes=40)
for k in range(400):
    ds.addSample(k,k%4)
print(type(ds))
# <class 'pybrain.datasets.classification.ClassificationDataSet'>
tstdata, trndata = ds.splitWithProportion(0.25)
print(type(trndata))
# <class 'pybrain.datasets.classification.ClassificationDataSet'>
print(type(tstdata))
# <class 'pybrain.datasets.classification.ClassificationDataSet'>
trndata._convertToOneOfMany()
tstdata._convertToOneOfMany()

我在代码和你的代码之间看到的唯一区别就是你对X的使用。也许你可以确认我的代码在你的机器上有效,如果有的话,那么如果混淆了什么我们可以查看X的内容吗?

答案 5 :(得分:0)

我发现最简单的解决方法是首先执行splitWithProportion(),更新类的数量,然后执行_convertToOneOfMany()。

tstdata, trndata = alldata.splitWithProportion( 0.25 )
tstdata.nClasses = alldata.nClasses
trndata.nClasses = alldata.nClasses
tstdata._convertToOneOfMany(bounds=[0, 1])
trndata._convertToOneOfMany(bounds=[0, 1])

通过更新testdata和trndata的nClasses,可以保证您不会在目标字段中获得不同的维度。

如果我第一次使用_convertToOneOfMany和第二次使用splitWithProportion,或者使用ClassificationDataSet时,我就会出现错误。所以,我建议并更新splitWithProportion函数。您可以在此pullRequest中看到整个代码。