Как можно ввести смесь двумерных и одномерных классов (однозначные и обычные целые числа соответственно) в последовательную модель Keras? - PullRequest
0 голосов
/ 26 мая 2018

У меня есть пандас DataFrame с 849743 строками и 13 столбцами, т. Е. Форма (849743,13).

Большинство этих столбцов просто содержат целые числа, однако 3 из них имеют закодированное в горячем видекатегориальные переменные.Они были не закодированы с использованием функций быстрого кодирования / встраивания Keras или sklearn (или любой другой библиотеки), я просто делал это вручную в python.

Например, df ['d'] - это столбец с закодированными в одну горячую переменную переменными, вот выдержка:

1082077    [0, 1, 0, 0, 0, 0, 0]
995216     [1, 0, 0, 0, 0, 0, 0]
924611     [0, 0, 0, 0, 1, 0, 0]
1171772    [0, 0, 0, 1, 0, 0, 0]
96796      [0, 0, 1, 0, 0, 0, 0]

Пожалуйста, игнорируйте бессмысленную индексацию Панд.

Это первая строка в столбце:

array([1, 0, 0, 0, 0, 0, 0])

Как видно, все элементы этого столбца DataFrame являются вложенными массивами.

Для дальнейшего понимания того, как структурирована структура данных Pandas, здесь приведены все элементы первой строки :

a                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
b                                  [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
c                                                                     1
d                                                 [1, 0, 0, 0, 0, 0, 0]
e                                                               1.53079
f                                                             -0.415253
g                                                             -0.425906
h                                                             -0.355143
i                                                             -0.249699
j                                                              -0.13448
k                                                              0.882726
l                                                               1.23091

Затем я преобразую это вnumpy массив с использованием:

x_train = df.values

При этом сохраняются исходные размеры DataFrame, которые являются (849743,13).

Я создал бессмысленную последовательность KerasМодель просто для проверки, будут ли работать входы, именно так я и обнаружил ошибку.Модель выглядит следующим образом:

# create model
model = Sequential()
model.add(Dense(130, input_dim=13, kernel_initializer='normal', 
          activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam')

Параметр input_dim был установлен равным 13, поскольку в массиве DataFrame / numpy имеется 13 столбцов, однако я считаю, что проблема связана с вложенными массивами numpy в 3.колонки с горячим кодированием.

Я ввожу свой исходный массив с 13 столбцами, известный как x_train, наряду с y_train (переменными наблюдения) в функцию model.fit:

model.fit(x_train, y_train,
          epochs=20,
          batch_size=128)

Я получаю следующую ошибку:

    Bad input argument to theano function with name "train_function" at index 0 (0-based).  
Backtrace when that variable is created:

  File "C:\Users\Studying\AppData\Local\conda\conda\envs\Tensorflow-gpu\lib\site-packages\spyder\utils\site\sitecustomize.py", line 101, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)
  File "C:/Users/Studying/Documents/GitHub/IFN665/Machine Learning/keras_regression_practice.py", line 106, in <module>
    model = baseline_model(input_shape)
  File "C:/Users/Studying/Documents/GitHub/IFN665/Machine Learning/keras_regression_practice.py", line 23, in baseline_model
    model.add(Dense(130, input_dim=1, kernel_initializer='normal', activation='relu'))
  File "C:\Users\Studying\AppData\Local\conda\conda\envs\Tensorflow-gpu\lib\site-packages\keras\models.py", line 432, in add
    dtype=layer.dtype, name=layer.name + '_input')
  File "C:\Users\Studying\AppData\Local\conda\conda\envs\Tensorflow-gpu\lib\site-packages\keras\engine\topology.py", line 1426, in Input
    input_tensor=tensor)
  File "C:\Users\Studying\AppData\Local\conda\conda\envs\Tensorflow-gpu\lib\site-packages\keras\legacy\interfaces.py", line 87, in wrapper
    return func(*args, **kwargs)
  File "C:\Users\Studying\AppData\Local\conda\conda\envs\Tensorflow-gpu\lib\site-packages\keras\engine\topology.py", line 1337, in __init__
    name=self.name)
  File "C:\Users\Studying\AppData\Local\conda\conda\envs\Tensorflow-gpu\lib\site-packages\keras\backend\theano_backend.py", line 222, in placeholder
    x = T.TensorType(dtype, broadcast)(name)
setting an array element with a sequence.

Я попытался попробовать, удалив все столбцы с горячим кодированием и соответственно изменив переменную input_dim, он работает (работает в том смысле, что не работаетвызвать ошибку, модель, очевидно, является предиктором мусора).

Я не верю, что возможно (несмотря на отсутствие поиска) иметь массив пустых значений, в котором некоторые элементы являются двумерными, а некоторые - одномерными, например, для преобразования вложенных массивов с множественным кодированием, горячим кодированием, в двумерныесписки и позволяя всем остальным переменным оставаться 1D.

Я искал похожие вопросы на этом сайте, однако, все, что я нахожу в Keras и переменных быстрого кодирования, похоже, либо спрашивает, что это такое, либо как это сделать, не как получить комбинацию из однозначных кодированных и 1D целочисленных входов.

Как это можно сделать?Я что-то упускаю из виду очевидно?

1 Ответ

0 голосов
/ 26 мая 2018

Проблема в том, что ваши данные не являются единообразными, когда вы конвертируете их в массив NumPy, некоторые записи снова становятся массивами, в том числе горячими, это приводит к несоответствию формы / типа.У вас есть 2 варианта в зависимости от того, как вы хотите обработать данные:

  1. Сгладьте внутренние массивы, чтобы получить окончательную форму (сэмплы,> 13).Под сглаживанием я подразумеваю иметь больше столбцов в массиве NumPy для закодированных данных в горячем виде.Строка будет выглядеть как смесь [0,0,1,0,0,..., 2.3492,1.3483,...], поэтому форма соответствует.Тогда ваш input_dim=len(data[0])
  2. Если вам действительно нужны отдельные входы, возможно, вы захотите обрабатывать их по-разному, например, переходить в разные плотные слои и т. Д., Вам потребуется обновить до функционального API .Это была бы модель с несколькими входами, и документация хорошо объясняет это.
...