В этом проекте мы пытаемся спрогнозировать чистую почасовую выработку энергии (EP) электростанции с комбинированным циклом, используя метод линейной регрессии.

Этот набор данных взят из Репозитория машинного обучения UCI https://archive.ics.uci.edu/ml/datasets/Combined+Cycle+Power+Plant

Мы попытаемся предсказать выход энергии, которая является непрерывной величиной, используя четыре различных функции в качестве входных данных. Для такого рода проблем хорошо подходит модель линейной регрессии. Мы будем использовать специальную технику оптимизации, называемую методом стохастического градиентного спуска (SGD), чтобы получить оптимизированные параметры.

# basic libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

Данные

Наши данные состоят из четырех почасовых характеристик окружающей среды

  1. Температура (Т)
  2. Давление окружающей среды (АР)
  3. Относительная влажность (RH)
  4. Выпускной вакуум (V)
  5. Наша целевая переменная – выход энергии (EP).
ccpp = pd.read_csv(‘Data/CCPP/ccpp.csv’)
ccpp.head()
+ — — — -+ — — — -+ — — — -+ — — — — -+ — — — -+ — — — — +
| S.no.  |   AT   |    V   |    AP    |   RH   |    EP   |
+ — — — -+ — — — -+ — — — -+ — — — — -+ — — — -+ — — — — +
| 0      | 8.34   | 40.77  | 1010.84  | 90.01  | 480.48  |
| 1      | 23.64  | 58.49  | 1011.4   | 74.2   | 445.75  |
| 2      | 29.74  | 56.9   | 1007.15  | 41.91  | 438.76  |
| 3      | 19.07  | 49.69  | 1007.22  | 76.79  | 453.09  |
| 4      | 11.8   | 40.66  | 1017.13  | 97.2   | 464.43  |

Исследовательский анализ данных

Количество строк и столбцов в фрейме данных

print('No. of Rows: ', ccpp.shape[0])
print('No. of Columns: ', ccpp.shape[1])
No. of Rows:  9568
No. of Columns:  5

Разделение функций и целевого значения

# Features 
x = ccpp.iloc[:, :-1]
y = ccpp.iloc[:, -1]

Блочная диаграмма

Блочная диаграмма данных для понимания масштаба данных

# Scale of Data
ccpp.boxplot(color = "black")
plt.xlabel("Attributes")
plt.ylabel("Scale");
plt.savefig("boxplot.jpg")

Как видно из рисунка, разные функции имеют разный масштаб

Тепловая карта

Поиск корреляции между переменными признаков, чтобы выяснить, какие отношения имеют разные переменные.

sns.heatmap(x.corr(), cmap="YlGnBu", linewidths=0.8, annot=True)
plt.savefig("heatmap.png")

Распределение

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

fig, ax = plt.subplots(2,2)
col = iter(x.columns)                   # iterator
for i in [0,1]:
    for j in [0,1]:
        sns.kdeplot(x[next(col)],color = "dodgerblue", fill = True, ax = ax[i,j])
plt.tight_layout()
plt.savefig("images/Distribution.jpg")

Выборка данных

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

Мы будем использовать функцию sklearn traintestsplit(), которая будет автоматически перемешивать и разделять данные для нас.

# split the data into test and training sets
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test= \
train_test_split(x,y,test_size=0.50, random_state=20)

Тренировочные данные

Как видно из рисунка, тестовые данные сохранили характерное распределение набора данных и являются репрезентативными для генеральной совокупности.

# Training set is well representative subset of the actual dataset
fig, ax = plt.subplots(2,2)
col = iter(x_train.columns) # iterator
for i in [0,1]:
 for j in [0,1]:
 sns.kdeplot(x_train[next(col)],color = “magenta”, fill = True, ax = ax[i,j])
plt.tight_layout()

Масштабирование

Поскольку мы используем алгоритм SGD в качестве оптимизатора, важно, чтобы мы масштабировали наши данные, чтобы избежать проблемы взрывающегося градиента

Мы будем использовать метод Standard Scaler, используя стандартную оценку z, заданную

где

x — образец

μ среднее значение

σ – стандартное отклонение

Использование функции Sklearn StandardScaler() автоматически масштабирует данные

# Scaling training data
from sklearn.preprocessing import StandardScaler
scalar = StandardScaler()
x_scaled_train = scalar.fit_transform(x_train)
x_scaled_test = scalar.transform(x_test)

Линейная регрессия

Теперь мы реализуем нашу линейную регрессию, используя технику регрессии SGD, чтобы вычислить коэффициент нашей линейной модели. Мы можем использовать функцию SGDRegressor из sklearn для расчета коэффициентов.

from sklearn.linear_model import SGDRegressor
sgr = SGDRegressor(max_iter=1000, eta0 = 0.01)
sgr.fit(x_scaled_train, y_train)
print(sgr.coef_)
[-14.83958743  -2.86265782   0.28195519  -2.30598442]

Точность

Мы рассчитаем точность этой модели, используя среднеквадратичную ошибку (RMSE)

sgrmse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(sgrmse)
print(rmse)
4.638256925600261

Поскольку значение RMSE довольно низкое, мы можем сделать вывод, что наша модель хорошо предсказывает целевую переменную