Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

МО_Иванова_4117_ЛР_4

.docx
Скачиваний:
1
Добавлен:
29.04.2025
Размер:
310.3 Кб
Скачать

ГУАП

КАФЕДРА № 41

ОТЧЕТ

ЗАЩИЩЕН С ОЦЕНКОЙ

ПРЕПОДАВАТЕЛЬ

Старший преподаватель

В.В.Боженко

должность, уч. степень, звание

подпись, дата

инициалы, фамилия

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №4

ПРОГНОЗИРОВАНИЕ ВРЕМЕННОГО РЯДА

по курсу: МАШИННОЕ ОБУЧЕНИЕ

РАБОТУ ВЫПОЛНИЛА

СТУДЕНТКА ГР.

4117

А.В.Иванова

подпись, дата

инициалы, фамилия

Санкт-Петербург 2024

Цель работы:

Выполнить прогнозирование временного ряда

Ссылка на colab:

https://colab.research.google.com/drive/163ygJbi_Df06YRBX1BlzE3cMc12QJxu4?usp=sharing

Задание:

Вариант 10: выполнить прогнозирование временного ряда объема выработки электроэнергии крупной электростанции (в млн. кВт. Ч) по месяцам с 1999 по 2003 гг.

Ход работы:

Набор данных был представлен в виде таблицы. Поэтому решено было скопировать данные в excel файл, откуда загрузить в Colab в виде датасета при помощи библиотеки pandas. В качестве целевого признака будет рассматриваться столбец 'данные' - с показателями выработанной электроэнергии.

Для начала построен график изменения объемов выработки электроэнергии по месяцам. Как видно (Рисунок 1) с годами вырабатываемый объем снижался, имея небольшие скачки в росте в конце каждого года. Однако после 5 лет скачкообразного спада объем выработки снова начал немного возрастать.

Рисунок 1 – График изменения объема выработки энергии по месяцам

В данном задании требуется реализовать Сеть радиально-базисных функций. Это искусственная нейронная сеть, которая использует радиальные базисные функции в качестве функций активации.

В данном случае сеть представляет из себя полно связную модель, состоящую из 4 полно связных слоёв: входного, двух скрытых и выходного, а также слоя Dropout, добавленного для случайного сброса некоторых значений нейронов во избежание переобучения. На последнем скрытом слое в качестве функции активации использовалась радиально базисная функция, которая разрабатывалась вручную и представлена как функция custom_activation.

На других слоях в качестве функции активации была выбрана relu. На выходном слое используется линейная, так как использование других функций активации вида sigmoid, relu или softmax привело к высокой неточности модели.

После создания функции активации была разработана модель нейронной сети. На вход подавались два параметры: год и месяц. На выходном слое один нейрон - предсказанное значение объёма выработки электроэнергии.

Перед использование модели было необходимо обработать входные параметры. Для предсказания используется номер месяца с учетом года, поэтому в качестве данных для обучения был взят столбец значений 'время'. Предсказывалось значение объёма вырабатываемой электроэнергии, поэтому в качестве y взят столбец 'данные', где записан вырабатываемый объем энергии.

Далее наборы разбиты на тренировочную и валидационную выборки в соотношении 4 к 1. После чего модель собрана и проведено обучение в 80 эпох, с размером рассматриваемого пакета 12. В результате на последней эпохе (Рисунок 2) были получены следующие результаты метрик: ошибка на тренировочных данных достаточно мала, но на реальных гораздо выше, что может свидетельствовать о переобучении, вызванном таким небольшим набором данных, состоящим всего из 60 значений.

Рисунок 2 – Результаты обучения построенной модели

Далее на основе полученных предсказаний выстроена диаграмма остатков (Рисунок 3). Одно из основных предположений линейной регрессии состоит в том, что остатки нормально распределены.

В данном случае можно утверждать, что предсказания модели выше, чем реальные значения, тем не менее остатки распределены относительно равномерно. Достаточно много нулевых- около нулевых остатков.

Рисунок 3 – Гистограмма остатков

Модель была успешно обучена, после чего можно было использовать ее для предсказания объемов выработки энергии на следующий месяц.

Следующее значение входных параметров [2004, 1] или январь 2004 года. Выполнено следующее предсказание (Рисунок 4).

Рисунок 4 – Предсказание на 1 месяц

Предсказанное значение - 48.46 кВт /ч больше, чем было за предыдущий месяц, что похоже на правду при наблюдаемом в начале нового года росте выработки.

Далее было выполнено прогнозирование временного ряда на 6 месяцев вперед (Рисунок 5).

Рисунок 5 – Предсказание на полгода вперед

Аналогичным образом выполнено предсказание на 1 год вперед (Рисунок 6).

Рисунок 6 – Предсказание на год вперед

Полученные результаты отображены на графике (Рисунок 7) изменения объема вырабатываемой энергии по месяцам. Модель предсказала новый скачок роста вырабатываемого объема в новом году.

Рисунок 7 – График предсказанного поведения объемов выработки энергии на следующие 12 месяцев

Вывод:

В результаты выполнения работы произошло ознакомление с временными рядами. Была изучена сеть радиально-базисных функций. На полученном графике аппроксимации видно, что модель утверждает рост объема вырабатываемой энергии. Гистограмма остатков показала допустимый результат с половиной нулевых остатков и относительно равномерным распределением.

Рассмотренные сети RBF полезны, когда требуется быстрое и эффективное обучение и когда структура данных не линейна. Они особенно хороши в задачах, где важна способность к обобщению с небольшим количеством обучающих данных, как в данной задаче, где набор был ограничен 60 показателями за 60 месяцев.

Полный код реализации задачи приведен в Приложении А.

ПРИЛОЖЕНИЕ А. ПОЛНЫЙ ПРОГРАММНЫЙ КОД.

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split

df = pd.read_excel('/content/lab4_data.xlsx', index_col=0)

energy = np.array(df['данные'])

plt.figure(figsize=(12, 6))

plt.plot(range(1,61), energy, label='Данные')

plt.xlabel('Месяц')

plt.ylabel('Выработка электроэнергии')

plt.title('Предсказание объема выработки электроэнергии')

plt.legend()

plt.show()

from keras import backend as K

def custom_activation(r):

    K.set_epsilon(0.1)

    return K.sqrt(1 + (r*K.epsilon())*(r*K.epsilon()))

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import Input

from keras.layers import Dropout, BatchNormalization

model = Sequential()

model.add(Input(shape=(1,)))

model.add(Dense(64, activation="relu"))

model.add(Dropout(0.2))

model.add(Dense(128, activation="relu"))

model.add(BatchNormalization())

model.add(Dense(200, activation=custom_activation))

model.add(Dense(1))  # Линейная функция активации

from sklearn.preprocessing import MinMaxScaler

X = np.array(df['время']).reshape(-1, 1)

y =  np.array(df['данные']).reshape(-1, 1)

X_train = X[:48]

y_train = y[:48]

X_test = X[48:60]

y_test = y[48:60]

model.compile(loss="mean_squared_error", optimizer="adam", metrics=["mean_absolute_error"])

model.fit(X_train, y_train, epochs=80, batch_size=12, validation_split=0.2)

predictions_valid = model.predict(X_test)

residuals = y_test - predictions_valid[0]

plt.figure(figsize=(12, 6))

plt.hist(residuals, bins=20, color='skyblue', edgecolor='black', alpha=0.7)

plt.xlabel('Остатки')

plt.ylabel('Частота')

plt.title('Гистограмма остатков')

plt.grid(axis='y', alpha=0.75)

plt.show()

next_data = np.array([61]).reshape(-1, 1)

next_prediction = model.predict(next_data)

print(f'Прогноз на следующий месяц: {next_prediction} кВт / час')

rolling_window_predictions = []

for i in range(1, 7):

    prediction_data = np.array([60+i]).reshape(-1, 1)

    prediction = model.predict(prediction_data)

    rolling_window_predictions.append(prediction[0][0])

print(f'Прогнозы на следующие 6 месяцев: {rolling_window_predictions}')

print('Прогнозы на следующие 6 месяцев:')

for prediction in rolling_window_predictions:

    print(prediction)

predictions_valid = model.predict(X)

rolling_window_predictions = []

for i in range(1, 13):

    prediction_data = np.array([60 + i]).reshape(-1, 1)

    prediction = model.predict(prediction_data)

    rolling_window_predictions.append(prediction[0][0])

print(f'Прогнозы на следующие 12 месяцев: {rolling_window_predictions}')

print('Прогнозы на следующие 12 месяцев:')

for prediction in rolling_window_predictions:

    print(prediction)

#добавляем 12 пустых значений

extended_y = np.pad(y.flatten(), (0, 12), 'constant', constant_values=(0,))

#объединение всех предсказанных значений

all_predictions = np.concatenate([predictions_valid.flatten(), np.array(rolling_window_predictions).flatten()])

plt.figure(figsize=(12, 6))

plt.plot(np.arange(1, 73), extended_y, label='Данные')

plt.plot(np.arange(1, 73), all_predictions, label='Предсказание', linestyle='dashed')

plt.xlabel('Месяц')

plt.ylabel('Объём выработки электроэнергии')

plt.title('Предсказание объёма выработки электроэнергии')

plt.legend()

plt.show()

Соседние файлы в предмете Машинное обучение