如何将向量中的数值和分类值组合为 LSTM 的输入?
How to combine numerical and categorical values in a vector as input for LSTM?
import pandas as pd
import numpy as np
rands = np.random.random(7)
days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
dates = pd.date_range('2018-01-01', '2018-01-07')
df = pd.DataFrame({'date': dates, 'days': days, 'y': rands})
df_days_onehot = pd.get_dummies(df.days)[days]
df[days] = df_days_onehot
df['target'] = df.y.shift(-1)
df.drop('days', axis=1, inplace=True)
df.set_index('date', inplace=True)
X = df.iloc[:, :-1].values
y = df.iloc[:, -1].values
我在上面分享了一个代码示例。我的问题是我应该如何将数值变量和分类变量组合为 LSTM 的输入?
输入向量应该是什么样的?
- 是否应该像 [0.123, 0, 1, 0, 0 ...] (如代码中的 X) dim = (1,8)?
- 是否应该像 [0.123, [0, 1, 0, 0...]] dim(1,2)
- 或者是否有特定的 way/ways 将输入传递给 ANN 或 RNN 等。如果有,它是什么,为什么我们应该使用 it/them (pros/cons)?
我阅读了有关嵌入的内容,但这些解释对我来说似乎还不够,因为我想了解所有这些内容背后的逻辑。
像这样...
model = Sequential()
model.add(LSTM(64, batch_input_shape=(batch_size, look_back, 1), stateful=True, return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(32, batch_input_shape=(batch_size, look_back, 1), stateful=True))
model.add(Dropout(0.3))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer=adam)
model.fit(trainX, trainY, epochs=100, batch_size=batch_size, verbose=2, shuffle=False)
任何指导、link、解释或帮助都将得到应用...祝你有美好的一天。
一般情况下,在处理各种范围的输入(如归一化等)时,可以考虑进行多种预处理。一个热表示当然是表示类别的好方法。
当类别元素太多导致一个热编码非常大时,使用嵌入。它们提供对给定输入进行编码的矢量表示(可能是可训练的)。您可以在下面的 link 中阅读更多关于它们的信息。嵌入的使用在 NLP 中非常普遍。
https://towardsdatascience.com/deep-learning-4-embedding-layers-f9a02d55ac12
除此之外,您还可以利用 Keras 建模支持多个输入层这一事实。
针对您的具体情况,这里有一个可能会帮助您入门的虚构示例。同样,我添加了几个密集的隐藏层只是为了证明这一点。它应该是不言自明的
X1 = rands
X2 = df_days_onehot
Y = np.random.random(7)
float_input = Input(shape=(1, ))
one_hot_input = Input(shape=(7,) )
first_dense = Dense(3)(float_input)
second_dense = Dense(50)(one_hot_input)
merge_one = concatenate([first_dense, second_dense])
dense_inner = Dense(10)(merge_one)
dense_output = Dense(1)(dense_inner)
model = Model(inputs=[float_input, one_hot_input], outputs=dense_output)
model.compile(loss='mean_squared_error',
optimizer='adam',
metrics=['accuracy'])
model.summary()
model.fit([X1,X2], Y, epochs=2)
另一种方法(可能更优雅)是以分类变量为条件(其值不随时间变化)。
让我们以两个不同城市的天气数据为例:巴黎和旧金山。你想根据历史数据预测下一个温度。但与此同时,您预计天气会根据城市而变化。您可以:
将辅助特征与时间序列数据结合起来(你在这里建议的)。
将辅助特征与RNN层的输出连接起来。这是某种 post-RNN 调整,因为 RNN 层不会看到此辅助信息。
或者仅使用条件的学习表示来初始化 RNN 状态(例如巴黎或旧金山)。
我写了一个库来调节辅助输入。它抽象了所有的复杂性,并被设计为尽可能user-friendly:
https://github.com/philipperemy/cond_rnn/
希望对您有所帮助!
import pandas as pd
import numpy as np
rands = np.random.random(7)
days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
dates = pd.date_range('2018-01-01', '2018-01-07')
df = pd.DataFrame({'date': dates, 'days': days, 'y': rands})
df_days_onehot = pd.get_dummies(df.days)[days]
df[days] = df_days_onehot
df['target'] = df.y.shift(-1)
df.drop('days', axis=1, inplace=True)
df.set_index('date', inplace=True)
X = df.iloc[:, :-1].values
y = df.iloc[:, -1].values
我在上面分享了一个代码示例。我的问题是我应该如何将数值变量和分类变量组合为 LSTM 的输入?
输入向量应该是什么样的?
- 是否应该像 [0.123, 0, 1, 0, 0 ...] (如代码中的 X) dim = (1,8)?
- 是否应该像 [0.123, [0, 1, 0, 0...]] dim(1,2)
- 或者是否有特定的 way/ways 将输入传递给 ANN 或 RNN 等。如果有,它是什么,为什么我们应该使用 it/them (pros/cons)?
我阅读了有关嵌入的内容,但这些解释对我来说似乎还不够,因为我想了解所有这些内容背后的逻辑。
像这样...
model = Sequential()
model.add(LSTM(64, batch_input_shape=(batch_size, look_back, 1), stateful=True, return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(32, batch_input_shape=(batch_size, look_back, 1), stateful=True))
model.add(Dropout(0.3))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer=adam)
model.fit(trainX, trainY, epochs=100, batch_size=batch_size, verbose=2, shuffle=False)
任何指导、link、解释或帮助都将得到应用...祝你有美好的一天。
一般情况下,在处理各种范围的输入(如归一化等)时,可以考虑进行多种预处理。一个热表示当然是表示类别的好方法。
当类别元素太多导致一个热编码非常大时,使用嵌入。它们提供对给定输入进行编码的矢量表示(可能是可训练的)。您可以在下面的 link 中阅读更多关于它们的信息。嵌入的使用在 NLP 中非常普遍。
https://towardsdatascience.com/deep-learning-4-embedding-layers-f9a02d55ac12
除此之外,您还可以利用 Keras 建模支持多个输入层这一事实。
针对您的具体情况,这里有一个可能会帮助您入门的虚构示例。同样,我添加了几个密集的隐藏层只是为了证明这一点。它应该是不言自明的
X1 = rands
X2 = df_days_onehot
Y = np.random.random(7)
float_input = Input(shape=(1, ))
one_hot_input = Input(shape=(7,) )
first_dense = Dense(3)(float_input)
second_dense = Dense(50)(one_hot_input)
merge_one = concatenate([first_dense, second_dense])
dense_inner = Dense(10)(merge_one)
dense_output = Dense(1)(dense_inner)
model = Model(inputs=[float_input, one_hot_input], outputs=dense_output)
model.compile(loss='mean_squared_error',
optimizer='adam',
metrics=['accuracy'])
model.summary()
model.fit([X1,X2], Y, epochs=2)
另一种方法(可能更优雅)是以分类变量为条件(其值不随时间变化)。
让我们以两个不同城市的天气数据为例:巴黎和旧金山。你想根据历史数据预测下一个温度。但与此同时,您预计天气会根据城市而变化。您可以:
将辅助特征与时间序列数据结合起来(你在这里建议的)。
将辅助特征与RNN层的输出连接起来。这是某种 post-RNN 调整,因为 RNN 层不会看到此辅助信息。
或者仅使用条件的学习表示来初始化 RNN 状态(例如巴黎或旧金山)。
我写了一个库来调节辅助输入。它抽象了所有的复杂性,并被设计为尽可能user-friendly:
https://github.com/philipperemy/cond_rnn/
希望对您有所帮助!