我可以通过哪种技术适应时间序列来替换 Python 中的 Keras MLP 回归模型中的交叉验证

By which technique adapted to time-series can I replace cross-validation in my Keras MLP regression model in Python

我目前正在处理一个包含 46 行的时间序列数据集,这些数据集是关于一周内每天大约每 3 小时进行一次气象测量的。我的解释变量 (X) 由 26 个变量组成,一些变量具有不同的测量单位(度、米、g/m3 等)。我要解释的变量(y)只由一个变量温度组成。

我的目标是使用变量集合 (X) 预测 12h-24h 时间段内的温度 (y)

为此,我使用了 Keras Tensorflow 和 Python,以及 MLP 回归模型:

X = df_forcast_cap.loc[:, ~df_forcast_cap.columns.str.startswith('l')] 
X = X.drop(['temperature_Y'],axis=1)
y = df_forcast_cap['temperature_Y']
y = pd.DataFrame(data=y)

# normalize the dataset X
scaler = MinMaxScaler(feature_range=(0, 1))
scaler.fit_transform(X)
normalized = scaler.transform(X)

# normalize the dataset y
scaler = MinMaxScaler(feature_range=(0, 1))
scaler.fit_transform(y)
normalized = scaler.transform(y)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# define base model
def norm_model():
    # create model
    model = Sequential()
    model.add(Dense(26, input_dim=26, kernel_initializer='normal', activation='relu'))# 30 is then number of neurons
    #model.add(Dense(6, kernel_initializer='normal', activation='relu'))
    model.add(Dense(1, kernel_initializer='normal'))

    # Compile model
    model.compile(loss='mean_squared_error', optimizer='adam')
    return model

# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

# evaluate model with standardized dataset
estimator = KerasRegressor(build_fn=norm_model, epochs=(100), batch_size=5, verbose=1)
kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(estimator, X, y, cv=kfold)

print(results)

[-0.00454741 -0.00323181 -0.00345096 -0.00847261 -0.00390925 -0.00334816
 -0.00239754 -0.00681044 -0.02098541 -0.00140129]


# invert predictions
X_train = scaler.inverse_transform(X_train)
y_train = scaler.inverse_transform(y_train)
X_test = scaler.inverse_transform(X_test)
y_test = scaler.inverse_transform(y_test)
results = scaler.inverse_transform(results)

print("Results: %.2f (%.2f) MSE" % (results.mean(), results.std()))
Results: -0.01 (0.01) MSE

(1) 我读到交叉验证不适用于时间序列预测。所以,我想知道还有哪些技术存在,哪些技术更适合时间序列。

(2) 其次,我决定对我的数据进行归一化,因为我的 X 数据集由不同的指标(度数、最小单位、g/m3 等)组成,而我用来解释 y 的变量是度数.通过这种方式,我知道必须处理更复杂的 MSE 解释,因为它的结果不会与我的 y 变量相同。但是对于我研究的下一步,我需要保存 y 预测的结果(由 MLP 模型生成)并且我需要这些值是度数。因此,我尝试反转归一化但没有成功,当我打印结果时,预测值仍为归一化格式(请参阅上面的代码)。有人看到我的 mistake.s 吗?

您在上面展示的模型正在查看 26 个测量值的单个实例来进行预测。根据您的描述,您似乎想根据这些测量的序列进行预测。我不确定我是否完全理解了描述,但我假设您有一系列 46 个测量值,每个测量值有 26 个值,您认为这些值应该是温度的良好预测指标。如果是这种情况,模型的输入形状应该是 (46, 26,)。这里的46叫做time_steps,26是特征个数

对于时间序列,您需要 select 模型设计。有两种方法:循环网络或卷积网络(或第二种方法的混合)。卷积网络通常用于检测输入数据中可能位于数据中某处的模式。例如,假设您想要检测图像中的给定形状。卷积网络是一个很好的起点。循环网络,在每个时间步后更新其内部状态。它们可以像卷积网络一样检测模式,但您可以认为它们的位置独立性较低。

卷积方法的简单示例。

import tensorflow as tf
from tensorflow import keras

from tensorflow.keras.layers import *
from tensorflow.keras.models import Sequential, Model

average_tmp = 0.0

model = Sequential([
    InputLayer(input_shape=(46,26,)),
    Conv1D(16, 4),
    Conv1D(32, 4),
    Conv1D(64, 2),
    Conv1D(128, 4),
    MaxPooling1D(),
    Flatten(),
    Dense(256, activation='relu'),
    Dense(1, bias_initializer=keras.initializers.Constant(average_tmp)),
])

model.compile('adam', 'mse')
model.summary()

一种混合方法,将用 LSTM 节点替换上面的“Flatten”层。这可能是开始试验的合理起点。

(1) I read that cross-validation is not adapted for time series prediction. So, I'm wondering which others techniques exist and which one is more adapted to time-series.

交叉验证是一种非常适合这个问题的技术。如果您尝试上面的示例模型,我几乎可以保证它会非常显着地过度拟合您的数据集。 cross-validation 可以帮助您为模型确定正确的正则化参数以避免过度拟合。

您可能想要考虑的正则化技术示例:

  • 在验证分数较低的时期保存模型权重。
  • Dropout and/or BatchNormalization。
  • 内核正则化。

(2) In a second place, I decided to normalize my data because my X dataset is composed of different metrics (degree, minimeters, g/m3 etc.) and my variable to explain y is in degree.

好电话。它将避免模型的训练周期试图从随机初始化中发现非常高值的偏差。

In this way, I know that have to deal with a more complicated interpretation of the MSE because its result won't be in the same unity that my y variable.

这是正交的。假定输入与 y 的单位不同。我们假设在 DNN 中我们可以创建权重线性变换的组合(加上 non-linear 激活)。这没有隐含的单位假设。

But for the next step of my study I need to save the result of the y predicted (made by the MLP model) and I need that these values be in degree. So, I tried to inverse the normalization but without success, when I print my results, the predicted values are still in normalized format (see in my code above). Does anyone see my mistake.s ?

scaler.inverse_transform(results) 应该可以解决问题。 对输入 X_ 和 Y_ 进行逆变换是没有意义的。它可能会帮助您保持代码的直接性,不要对 X 和 Y 缩放器使用相同的变量名。

也可以避免缩放 Y。如果您选择这样做,我建议您使用 Y 的平均值初始化输出层偏差。