我有一个pandas 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]
请忽略无意义的Pandas索引。
这是该列中的第一行:
array([1, 0, 0, 0, 0, 0, 0])
如您所见,这个DataFrame列的元素都是嵌套的numpy数组。
为了进一步了解Pandas DataFrame的结构,以下是第一行的所有元素:
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 1d [1, 0, 0, 0, 0, 0, 0]e 1.53079f -0.415253g -0.425906h -0.355143i -0.249699j -0.13448k 0.882726l 1.23091
随后,我使用以下代码将其转换为numpy数组:
x_train = df.values
这保留了DataFrame的原始维度,即(849743,13)。
我创建了一个无意义的Keras Sequential模型,只是为了测试输入是否有效,这就是我最初发现错误的方式。模型如下:
# 创建模型model = Sequential()model.add(Dense(130, input_dim=13, kernel_initializer='normal', activation='relu'))model.add(Dense(1, kernel_initializer='normal'))# 编译模型model.compile(loss='mean_squared_error', optimizer='adam')
由于DataFrame/numpy数组中有13列,因此input_dim设置为13,但我认为问题出自3个独热编码列中的嵌套numpy数组。
我将包含13列的原始numpy数组(称为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变量,它确实有效(有效是指它不会导致错误,模型显然是一个垃圾预测器)。
我认为(尽管没有深入搜索)不可能有一个numpy数组,其中某些元素是2D而另一些是1D,例如将嵌套的numpy独热编码数组更改为2D列表,并允许所有其他变量保持1D。
我已经在这个网站上搜索了类似的问题,但是我找到的关于Keras和独热编码变量的所有内容似乎要么是询问它是什么,要么是如何做到的,不是如何混合使用独热编码和1D整数输入。
这该如何实现?我是否遗漏了什么明显的问题?
回答:
问题在于您的数据不一致,当您将其转换为NumPy数组时,一些条目再次是数组,即独热编码的那些,这导致了形状/类型不匹配。根据您希望如何处理数据,您有两个选项:
- 将内部数组展平,这样您的最终形状为(样本数,>13)。我的意思是为独热编码数据在NumPy数组中增加更多的列。一行看起来像混合体
[0,0,1,0,0,..., 2.3492,1.3483,...]
,这样形状是一致的。然后您的input_dim=len(data[0])
- 如果您真的想要单独的输入,也许您希望以不同的方式处理它们,比如传递到不同的Dense层等,您将需要升级到功能API。这将是一个多输入模型,文档对此有很好的解释。