Контекст
PJM Interconnection LLC (PJM) — региональная передающая организация (RTO) в США. Он является частью сети Eastern Interconnection, управляющей системой электропередачи, обслуживающей все или некоторые штаты Делавэр, Иллинойс, Индиана, Кентукки, Мэриленд, Мичиган, Нью-Джерси, Северная Каролина, Огайо, Пенсильвания, Теннесси, Вирджиния, Западная Вирджиния и округ. Колумбии.
Данные о почасовом потреблении энергии взяты с веб-сайта PJM и указаны в мегаваттах (МВт).
С течением времени регионы менялись, поэтому данные могут появляться только за определенные даты для каждого региона.
Импорт необходимых библиотек
import tensorflow as tf import pandas as pd import numpy as np import matplotlib.pyplot as plt import sklearn.preprocessing
Функция для построения серии
def plot_series(time, series, format="-", start=0, end=None): plt.plot(time[start:end], series[start:end], format) plt.xlabel("Time") plt.ylabel("Value") plt.grid(True)
Чтение набора данных
path = '/kaggle/input/hourly-energy-consumption/FE_hourly.csv' df = pd.read_csv(path)
Построение набора данных
df.plot() plt.show()
Масштабирование набора данных
scaler = sklearn.preprocessing.MinMaxScaler() df_norm = scaler.fit_transform(df['FE_MW'].values.reshape(-1,1)) df_norm.shape (62874, 1)
График мощности и времени
power = df_norm time = np.array(df.index) plt.figure(figsize=(10, 6)) plot_series(time, power)
Предварительная обработка набора данных
split_time = 50000 time_train = time[:split_time] x_train = power[:split_time] time_valid = time[split_time:] x_valid = power[split_time:] window_size = 30 batch_size = 32 shuffle_buffer_size = 1000 def windowed_dataset(series, window_size, batch_size, shuffle_buffer): series = tf.expand_dims(series, axis=-1) ds = tf.data.Dataset.from_tensor_slices(series) ds = ds.window(window_size + 1, shift=1, drop_remainder=True) ds = ds.flat_map(lambda w: w.batch(window_size + 1)) ds = ds.shuffle(shuffle_buffer) ds = ds.map(lambda w: (w[:-1], w[1:])) return ds.batch(batch_size).prefetch(1) def model_forecast(model, series, window_size): ds = tf.data.Dataset.from_tensor_slices(series) ds = ds.window(window_size, shift=1, drop_remainder=True) ds = ds.flat_map(lambda w: w.batch(window_size)) ds = ds.batch(32).prefetch(1) forecast = model.predict(ds) return forecast
Построение модели
tf.keras.backend.clear_session() tf.random.set_seed(51) np.random.seed(51) train_set = windowed_dataset(x_train, window_size=60, batch_size=100, shuffle_buffer=shuffle_buffer_size) model = tf.keras.models.Sequential([ tf.keras.layers.Conv1D(filters=60, kernel_size=5, strides=1, padding="causal", activation="relu", input_shape=[None, 1]), tf.keras.layers.LSTM(60,return_sequences=True), tf.keras.layers.Dense(10, activation ='relu'), tf.keras.layers.Dense(1), tf.keras.layers.Lambda(lambda x: x * 400) ])
Чтобы лучше понять приведенный выше код, я бы порекомендовал посмотреть этот туториал от Udacity. https://classroom.udacity.com/courses/ud187/lessons/6d543d5c-6b18-4ecf-9f0f-3fd034acd2cc/concepts/c10fb954-25ea-43e3-b22c-21b3e423eb05#
Компиляция модели
optimizer = tf.keras.optimizers.SGD(lr=1e-5, momentum=0.9) model.compile(loss=tf.keras.losses.Huber(), optimizer=optimizer, metrics=["mae"]) history = model.fit(train_set,epochs=1000)
В конце 1000-й эпохи мы получаем убыток 3,3108e-04 и среднюю абсолютную ошибку 0,0186.
Прогнозирование модели
rnn_forecast = model_forecast(model, power[..., np.newaxis], window_size) rnn_forecast = rnn_forecast[split_time - window_size:-1, -1, 0] plt.figure(figsize=(10, 6)) plot_series(time_valid, x_valid) plot_series(time_valid, rnn_forecast)
Фактический график против прогноза
plt.plot(time_valid[:300], x_valid[:300]) plt.plot(time_valid[:300], rnn_forecast[:300]) plt.xlabel("Time") plt.ylabel("Value") plt.grid(True)
Результаты
Мы получаем убыток 3,3108e-04 и среднюю абсолютную ошибку 0,0186. Мы можем улучшить нашу модель, используя более сложные слои. Если рассматривать ее как базовую модель, ее необходимо оптимизировать для повышения производительности.