AttributeError с использованием pyBrain _splitWithPortion - тип объекта изменился?
Я тестирую pybrain, следуя основному учебному пособию по классификации, и по другому взгляду на него с некоторыми более реалистичными данными. Однако я получаю эту ошибку при применении trndata._convertToOneOfMany() с ошибкой:
AttributeError: 'SupervisedDataSet' object has no attribute '_convertToOneOfMany
Набор данных создается как объект классификация. Классификация DataSet, однако, вызывая splitWithProportion, кажется, изменяет его supervised.SupervisedDataSet, так что, будучи довольно новым для Python, эта ошибка не кажется такой неожиданной, поскольку supervised.SupervisedDataSet не имеет такого метода, ification.ClassificationDataSet делает. Код здесь.
Однако один и тот же точный код используется во многих уроках, и я чувствую, что, должно быть, что-то упустил, так как многие другие работают. Я смотрел на изменения в кодовой базе на 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 ответов
У меня такая же проблема. Я добавил следующий код, чтобы он работал на моей машине.
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] )
Это преобразует tstdata
а также trndata
назад к ClassificationDataSet
тип.
Реализация splitWithProportion
изменен между PyBrain версий 0.3.2 и 0.3.3., представляя эту ошибку, которая нарушает полиморфизм.
На данный момент библиотека не обновлялась с января 2015 года, поэтому использование какого-либо обходного пути - единственный способ на данный момент.
Вы можете проверить ответственный коммит здесь: https://github.com/pybrain/pybrain/commit/2f02b8d9e4e9d6edbc135a355ab387048a00f1af
У меня та же проблема, и я думаю, что я ее исправил: см. Этот запрос на извлечение.
(Python 2.7.6, PyBrain 0.3.3, OS X 10.9.5)
Я попробовал предложенный обходной путь от Muhammed Miah, но я все равно был сбит с толку при запуске учебника в строке:
print( trndata['input'][0], trndata['target'][0], trndata['class'][0])
trndata ['class'] был пустым массивом, поэтому 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)
Самый простой обходной путь, который я нашел, - это сначала выполнить 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])
А с обновлением nClasses как testdata, так и trndata это гарантирует, что вы не получите разные измерения в целевых полях.
Я получал ошибки, если я сначала сделал _convertToOneOfMany и второй splitWithProportion, или наоборот при работе с ClassificationDataSet. Итак, я предложил и обновил в функции splitWithProportion. Вы можете увидеть весь код в этом pullRequest.
Итак, я сделал следующее без ошибки:
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, если что-то запутывает?