Búsqueda de sitios web

Previsión meteorológica mediante redes LSTM


Introducción

Las redes de memoria larga a corto plazo (LSTM) son una clase de redes neuronales recurrentes (RNN) que son capaces de resolver problemas de predicción de secuencias. Los RNN y LSTM en particular se diferencian de otras redes neuronales en que tienen una dimensión temporal y tienen en cuenta el tiempo y la secuencia. De hecho, se consideran el subgrupo de RNN más eficaz y conocido; pertenecen a una clase de redes neuronales artificiales creadas para identificar patrones en secuencias de datos, incluidos datos de series temporales numéricas. En este artículo, presentaremos

esta subclase de redes y úsela para construir un modelo de pronóstico del tiempo.

Requisitos previos

  • Programación básica de Python: familiaridad con Python y bibliotecas clave como NumPy, Pandas y Matplotlib para el manejo y visualización de datos.

  • Comprensión de los conceptos de aprendizaje automático: conocimiento de los fundamentos del aprendizaje automático, incluido el aprendizaje supervisado, el sobreajuste y la evaluación de modelos.

  • Conceptos básicos del aprendizaje profundo: comprensión de los conceptos básicos de las redes neuronales, la retropropagación y las funciones de activación.

  • Redes LSTM (memoria larga a corto plazo): familiaridad con las redes neuronales recurrentes (RNN) y específicamente las LSTM, incluida su arquitectura, puertas (entrada, olvido y salida) y cómo manejan datos secuenciales.

  • Habilidades de preprocesamiento de datos: experiencia en normalización de datos, manejo de valores faltantes y división de datos en conjuntos de entrenamiento, validación y prueba.

  • Análisis de series temporales: comprensión de los datos de series temporales, incluidas las tendencias, la estacionalidad y el ruido.

  • Experiencia con TensorFlow o PyTorch: experiencia básica en el uso de marcos de aprendizaje profundo como TensorFlow o PyTorch para construir y entrenar modelos de redes neuronales.

  • Acceso a conjuntos de datos meteorológicos: acceso a datos meteorológicos históricos para entrenar y probar el modelo LSTM, como datos de la Administración Nacional Oceánica y Atmosférica (NOAA) u otras fuentes relevantes.

  • Conocimiento básico de métricas de evaluación: familiaridad con métricas de evaluación específicas para problemas de regresión, como el error medio absoluto (MAE), el error cuadrático medio (RMSE) y el error cuadrático medio (MSE).

¿Qué son las redes de memoria a largo plazo?

Las redes de memoria a corto plazo (LSTM) se utilizan con frecuencia en problemas de predicción de secuencias. Estas redes neuronales recurrentes tienen la capacidad de aprender la dependencia de secuencias. El resultado del paso anterior se utiliza como entrada del siguiente paso en el RNN. Fueron Hochreiter y Schmidhuber quienes crearon originalmente la arquitectura de memoria a corto plazo. Abordó el problema de la “dependencia a largo plazo” de las RNN. Aquí es donde los RNN pueden predecir variables basadas en la información de los datos actuales, pero no pueden predecir variables mantenidas en la memoria a largo plazo. Sin embargo, el rendimiento de RNN no mejorará con una brecha cada vez mayor. Por diseño, se sabe que los LSTM almacenan datos durante mucho tiempo. Este método se emplea al analizar datos de series temporales, hacer predicciones y categorizar datos.

Teóricamente, los RNN clásicos son capaces de rastrear cualquier tipo de dependencia a largo plazo en las secuencias de entrada. Sin embargo, los RNN simples tienen el inconveniente de no ser aplicables a problemas del mundo real para este tipo de problemas. Los gradientes a largo plazo en las redes de retropropagación, por ejemplo, tienden a disminuir hasta cero o aumentar hasta el infinito. Esto depende de los cálculos necesarios para el proceso, que utilizan un conjunto de números de precisión finita.

Arquitectura de redes LSTM

La arquitectura de las redes LSTM utiliza cuatro redes neuronales y múltiples celdas o bloques de memoria que crean una estructura en cadena que constituye la memoria a corto plazo. Una unidad típica de memoria a largo y corto plazo se compone de una celda, una puerta de entrada, una puerta de salida y una puerta de olvido. La célula realiza un seguimiento de los valores durante cualquier cantidad de tiempo y las tres puertas regulan el flujo de información que entra y sale de la célula.

Puertas de entrada: Estas puertas seleccionan los valores de entrada que se aplicarán para modificar la memoria. Estos deciden si pasan o no datos 0 o 1 utilizando la función sigmoide. Además, puede utilizar la función tanh para asignar pesos a los datos que representen su importancia en una escala de -1 a 1. Olvídate de las puertas: Son las puertas responsables del primer paso del LSTM, que es decidir qué información descartar del estado de la celda. Esta decisión se toma en función de una capa sigmoidea. Observa el estado anterior _ht_−1 y la entrada xt, y genera un número entre 0 y 1 para cada valor en el estado de la celda. _Ct_−1. Un 1 representa un valor completamente conservado, mientras que un 0 representa uno completamente olvidado. Puertas de salida: esta clase final de puertas determina qué datos se enviarán a la salida. Esta salida, por muy filtrada que sea, se basará en el estado de nuestra celda. Primero ejecutamos una capa sigmoidea para determinar qué partes del estado de la celda se generarán. Luego, para generar solo las porciones que decidimos, multiplicamos el estado de la celda por la salida de la puerta sigmoidea después de pasar el estado de la celda a través de tanh para forzar que los valores caigan en el rango de - 1 y 1.

Diagrama de la arquitectura estructural de las redes LSTM (fuente)

Conjunto de datos meteorológicos

Debido a la necesidad constante de previsión meteorológica y predicción de desastres. Los conjuntos de datos meteorológicos son uno de los más presentes y accesibles en línea. En este tutorial, utilizaremos el conjunto de datos climáticos de Jena registrado por el Instituto Max Planck de Biogeoquímica.

Se trata de un conjunto de datos de series temporales para la ciudad de Jena en Alemania con registros que abarcan 10 minutos y que consta de 14 características (temperatura, humedad relativa, presión…). Está disponible para diferentes rangos de fechas, pero usaremos el registro de 6 meses del segundo semestre de 2021 en la universidad.

!curl https://www.bgc-jena.mpg.de/wetter/mpi_saale_2021b.zip -o mpi_saale_2021b.zip

Luego, extraeremos el contenido del zip en un archivo csv y vincularemos el contenido de éste a un marco de datos con la biblioteca pandas.

import zipfile
import pandas

zip_file = zipfile.ZipFile("mpi_saale_2021b.zip")
zip_file.extractall()
csv_path = "mpi_saale_2021b.csv"
data_frame = pandas.read_csv(csv_path)

Este marco de datos contendrá las 26495 filas de los registros de marca de tiempo de 6 meses de las 14 características climáticas antes mencionadas de la región de Jena.

Para predicciones a largo plazo (hasta 1 o 2 meses), se debe tener en cuenta todo el espectro de funciones. En nuestro caso, para fines de demostración de la red LSTM, pronosticaremos el clima para diferentes períodos que van desde unas pocas horas hasta unos pocos días. Entonces, usaremos, además del tiempo, solo seis características: temperatura, presión, humedad relativa, presión de vapor, velocidad del viento y hermeticidad.

time = data_frame['Date Time']
temperature = data_frame['T (degC)']
pressure = data_frame['p (mbar)']
relative_humidity = data_frame['rh (%)']
vapor_pressure = data_frame['VPact (mbar)']
wind_speed = data_frame['wv (m/s)']
airtight = data_frame['rho (g/m**3)']

Usando Matplotlib, podemos mostrar el gráfico a lo largo del tiempo de estas características.

import matplotlib.pyplot as plt
from matplotlib.pyplot import figure

plt.subplots(nrows=2, ncols=3, figsize=(26, 20))

ax = plt.subplot(2, 3, 1)
temperature.index = time
temperature.head()
temperature.plot(rot=20)
plt.title('Temperature')

ax = plt.subplot(2, 3, 2)
pressure.index = time
pressure.head()
pressure.plot(rot=20)
plt.title('Pressure')

ax = plt.subplot(2, 3, 3)
relative_humidity.index = time
relative_humidity.head()
relative_humidity.plot(rot=20)
plt.title('Relative Humidity')

ax = plt.subplot(2, 3, 4)
vapor_pressure.index = time
vapor_pressure.head()
vapor_pressure.plot(rot=20)
plt.title('Vapor Pressure')

ax = plt.subplot(2, 3, 5)
wind_speed.index = time
wind_speed.head()
wind_speed.plot(rot=20)
plt.title('Wind Speed')

ax = plt.subplot(2, 3, 6)
airtight.index = time
airtight.head()
airtight.plot(rot=20)
plt.title('Airtight')

plt.tight_layout()
plt.show()

Esto dará como resultado la siguiente imagen:

Preprocesamiento de datos

Muestreo descendente

En este caso elegimos 26.000 puntos de datos para el entrenamiento. Se realiza un registro de una observación cada 10 minutos, o seis veces por hora. Dado que no se anticipa ningún cambio significativo en 60 minutos, volveremos a muestrear los datos establecidos en un solo registro cada hora. Esto se puede ejecutar a través del parámetro sampling_rate del método timeseries_dataset_from_array de la biblioteca de preprocesamiento de Keras. Por lo tanto, este argumento debe establecerse en 6 para tener la muestra reducida requerida que estamos buscando.

Normalización de datos

Antes de entrenar la red neuronal, realizamos una normalización para limitar los valores de las características a un rango de 0 a 1 porque cada característica tiene valores con rangos variables. Para lograr esto, dividimos la desviación estándar de cada característica por su media antes de deducirla.

def normalize(data):
    data_mean = data.mean(axis=0)
    data_std = data.std(axis=0)
    return (data - data_mean) / data_std

Entonces, agrupemos las características seleccionadas en una sola matriz para aplicar esta función de normalización.

features = pandas.concat([temperature, pressure, relative_humidity, vapor_pressure, wind_speed, airtight], axis=1)
features.index = time
features

Matriz de datos antes de la normalización

features = normalize(features.values)
features = pandas.DataFrame(features)
features

Matriz de datos después de la normalización

Luego, dividiremos el conjunto de datos en entrenamiento y validación asignando el 80% del conjunto de datos al entrenamiento.

training_size = int ( 0.8 * features.shape[0])  
train_data = features.loc[0 : training_size - 1]
val_data = features.loc[training_size:]

Conjunto de datos de entrenamiento

Para cada predicción, utilizaremos los datos de seguimiento de los últimos 3 días, lo que equivale a alrededor de 432 marcas de tiempo (3 × 24 × 6=432).
Estos datos se utilizarán para predecir la temperatura después de 6 horas en el futuro, lo que equivale a 36 marcas de tiempo antes de la reducción de muestreo.

start = 432 + 36
end = start + training_size

x_train = train_data.values
y_train = features.iloc[start:end][[0]]

sequence_length = int(432 / 6)

Luego, construyamos el conjunto de datos de entrenamiento en su forma final utilizando la biblioteca de preprocesamiento Keras.

from tensorflow import keras

dataset_train = keras.preprocessing.timeseries_dataset_from_array(
    data=x_train,
    targets=y_train,
    sequence_length=sequence_length,
    sampling_rate=6,
    batch_size=64,
)

Conjunto de datos de validación

De manera similar, construiremos el conjunto de validación. Sin embargo, las últimas 468 (432 + 36) filas deben excluirse de los datos porque no tendremos información de etiqueta para esas entradas. Quitemos las 468 filas del final de los datos. Además, el conjunto de datos de la etiqueta de validación debe comenzar en la posición 468 después de la posición dividida del entrenamiento.

x_val_end = len(val_data) - start

label_start = training_size + start

x_val = val_data.iloc[:x_val_end][[i for i in range(6)]].values
y_val = features.iloc[label_start:][[0]]

dataset_val = keras.preprocessing.timeseries_dataset_from_array(
    x_val,
    y_val,
    sequence_length=sequence_length,
    sampling_rate=6,
    batch_size=64,
)

Creación de un modelo de pronóstico meteorológico LSTM

Primero, extraigamos un único lote del conjunto de datos de entrenamiento y usémoslo para tener la dimensión de la capa de entrada y salida. Luego, usaremos la biblioteca de capas de Keras para crear una capa LSTM con 32 unidades de memoria.

for batch in dataset_train.take(1):
    inputs, targets = batch
    
inputs = keras.layers.Input(shape=(inputs.shape[1], inputs.shape[2]))
lstm_out = keras.layers.LSTM(32)(inputs)
outputs = keras.layers.Dense(1)(lstm_out)

model = keras.Model(name="Weather_forcaster",inputs=inputs, outputs=outputs)
model.compile(optimizer=keras.optimizers.Adam(learning_rate=0.001), loss="mse")
model.summary()

El resumen de este modelo es el siguiente

Luego, ajustamos el modelo utilizando los conjuntos de datos de entrenamiento/validación y un número de época de 15 (determinado experimentalmente para nuestro conjunto de datos).

history = model.fit(
    dataset_train,
    epochs=15,
    validation_data=dataset_val
)

A continuación, mostramos los resultados del ajuste del modelo en términos de pérdida de entrenamiento a continuación.

loss = history.history["loss"]
epochs = range(len(loss))
plt.figure()
plt.plot(epochs, loss, "b", label="Training loss")
plt.title("Training Loss")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.show()

Después de obtener nuestro modelo entrenado, lo usaremos para predecir la temperatura normalizada para un valor en el conjunto de datos de validación. Luego, desnormalizaremos este valor usando la desviación estándar y la media de la temperatura, y trazaremos los resultados en un gráfico usando Matplotlib.

temp_mean = temperature.mean(axis=0)
temp_std = temperature.std(axis=0)

for x, y in dataset_val.skip(12):
    history_data = x[0][:, 1].numpy() * temp_std + temp_mean
    true_value = y[0].numpy() * temp_std + temp_mean
    prediction = model.predict(x)[0] * temp_std + temp_mean
    time_steps = list(range(-(history_data.shape[0]), 0))
    plt.plot(time_steps, history_data)
    plt.plot(36, true_value, "gD")
    plt.plot(36, prediction, "rX")
    plt.legend(["History", "True Future", "Model Prediction"])
    plt.xlabel("Time")
    plt.show()
    break

Conclusión

Las redes de memoria a corto plazo son un tipo de red neuronal recurrente que puede resolver problemas relacionados con la predicción de secuencias. Los RNN y LSTM, en particular, se diferencian de otras redes neuronales en que contienen una dimensión temporal y tienen en cuenta el tiempo y la secuencia. En esta publicación, presentamos esta subclase de red y la usamos para construir un modelo de pronóstico del tiempo. Probamos su eficacia como un subgrupo de RNN diseñados para detectar patrones en secuencias de datos, incluidos datos de series de tiempo numéricas.

Recursos

http://www.bioinf.jku.at/publications/older/2604.pdf

https://www.researchgate.net/publication/13853244_Long_Short-term_Memory

https://www.bgc-jena.mpg.de/wetter/

https://www.geeksforgeeks.org/introduction-to-recurrent-neural-network/

https://machinelearningmastery.com/time-series-prediction-with-deep-learning-in-python-with-keras/

Artículos relacionados: