如何将 2D 和 1D 类(分别为单热编码和常规整数)的混合输入到 Keras 顺序模型中?
How does one input a mixture of 2D and 1D classes (one-hot encoded & regular integers respectively) into the Keras Sequential Model?
我有一个 pandas DataFrame,有 849743 行和 13 列,即形状为 (849743,13)。
这些列中的大多数只包含整数,但是,其中 3 个具有单热编码的分类变量。它们 不是 使用 Keras 或 sklearn(或任何其他库)的一次性 encoding/embedding 功能编码,我只是在 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 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 Sequential 模型只是为了测试输入是否有效,这就是我最初发现错误的方式。模型如下:
# 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 列,但是,我认为问题出在 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 数组,其中某些元素是二维的,有些是一维的,例如将嵌套的 numpy、单热编码数组更改为二维列表并允许所有其他变量保持一维。
我在这个网站上搜索过类似的问题,但是,我发现的关于 Keras 和单热编码变量的所有内容似乎都在询问它是什么,或者如何去做,不是 如何混合使用单热编码和一维整数输入。
如何做到这一点?我错过了一些明显的东西吗?
问题是因为您的数据不统一,当您将其转换为 NumPy 数组时,一些条目又是数组,即热编码的条目,这会导致形状/类型不匹配。根据您希望如何处理数据,您有 2 个选项:
- 展平内部数组,所以你的最终形状是(样本,>13)。通过展平我的意思是在 NumPy 数组中有更多列用于单热编码数据。一行看起来像混合体
[0,0,1,0,0,..., 2.3492,1.3483,...]
,因此形状是一致的。那么你的input_dim=len(data[0])
- 如果你真的想要单独的输入,也许你想以不同的方式处理它们,比如传递到不同的 Dense 层等,你将需要升级到 functional API。这将是一个多输入模型,文档对其进行了很好的解释。
我有一个 pandas DataFrame,有 849743 行和 13 列,即形状为 (849743,13)。
这些列中的大多数只包含整数,但是,其中 3 个具有单热编码的分类变量。它们 不是 使用 Keras 或 sklearn(或任何其他库)的一次性 encoding/embedding 功能编码,我只是在 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 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 Sequential 模型只是为了测试输入是否有效,这就是我最初发现错误的方式。模型如下:
# 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 列,但是,我认为问题出在 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 数组,其中某些元素是二维的,有些是一维的,例如将嵌套的 numpy、单热编码数组更改为二维列表并允许所有其他变量保持一维。
我在这个网站上搜索过类似的问题,但是,我发现的关于 Keras 和单热编码变量的所有内容似乎都在询问它是什么,或者如何去做,不是 如何混合使用单热编码和一维整数输入。
如何做到这一点?我错过了一些明显的东西吗?
问题是因为您的数据不统一,当您将其转换为 NumPy 数组时,一些条目又是数组,即热编码的条目,这会导致形状/类型不匹配。根据您希望如何处理数据,您有 2 个选项:
- 展平内部数组,所以你的最终形状是(样本,>13)。通过展平我的意思是在 NumPy 数组中有更多列用于单热编码数据。一行看起来像混合体
[0,0,1,0,0,..., 2.3492,1.3483,...]
,因此形状是一致的。那么你的input_dim=len(data[0])
- 如果你真的想要单独的输入,也许你想以不同的方式处理它们,比如传递到不同的 Dense 层等,你将需要升级到 functional API。这将是一个多输入模型,文档对其进行了很好的解释。