1

我目前正在处理一个包含 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 模型生成),并且我需要这些值是度数。因此,我尝试反转归一化,但没有成功,当我打印结果时,预测值仍然是归一化格式(参见我上面的代码)。有人看到我的错误吗?

4

1 回答 1

1

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

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

卷积方法的简单示例。

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) 我读到交叉验证不适用于时间序列预测。所以,我想知道还有哪些其他技术存在,哪一种更适合时间序列。

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

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

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

(2) 其次,我决定对我的数据进行规范化,因为我的 X 数据集由不同的指标(度数、最小值、g/m3 等)组成,而我用来解释 y 的变量是以度数为单位的。

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

通过这种方式,我知道必须处理对 MSE 的更复杂的解释,因为它的结果不会与我的 y 变量具有相同的统一性。

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

但是对于我研究的下一步,我需要保存 y 预测的结果(由 MLP 模型生成),并且我需要这些值是度数。因此,我尝试反转归一化,但没有成功,当我打印结果时,预测值仍然是归一化格式(参见我上面的代码)。有人看到我的错误吗?

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

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

于 2019-07-11T11:45:40.313 回答