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