@ddukbbok_kang

하고 싶은 건 일단 해봅니다.

Python/딥러닝

LSTM으로 가전제품 에너지 사용량 예측해보기

강떡볶 2022. 5. 2. 15:13

 

 

LSTM 기본 개념 및 구조

LSTM이란? 순환 신경망(RNN)의 구조에 장/단기 기억을 가능하게 설계한 신경망의 구조 RNN의 Gradient Vanishing/Exploding Gradient를 해결하기 위해 고안 기억셀을 추가하여 경사 소멸 문제를 해결 LSTM이 RNN

ddukbbok-kang.tistory.com

지난 글에서는 LSTM 기본 개념 및 구조에 대해 정리했다.

이번 글에서는 이 LSTM 모델을 활용하여 가전제품 에너지 사용량을 예측해보고자 한다.

 

 

 

 

데이터 출처
  • Appliances energy prediction Data Set(가전제품 에너지 사용량 예측)
 

UCI Machine Learning Repository: Appliances energy prediction Data Set

Appliances energy prediction Data Set Download: Data Folder, Data Set Description Abstract: Experimental data used to create regression models of appliances energy use in a low energy building. Data Set Characteristics:   Multivariate, Time-Series Number

archive.ics.uci.edu

 

 

 

데이터 불러오기 및 전처리
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# 데이터 불러오기

df = pd.read_csv('C:/Users/hy101/Desktop/RNN&LSTM/energydata_complete.csv')
df

 

# 결측치 제거

df.dropna(how='any', inplace=True)
df
df.shape

 

# 날짜순으로 정렬
# 인덱스 초기화

df.sort_values(ascending=True, by='date', inplace=True)
df.reset_index(drop=True, inplace=True)
# 날짜형으로 변환

df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d %H:%M:%S')
plt.figure(figsize=(25, 9))
sns.lineplot(y=df['Appliances'], x=df.index)
plt.xlabel('Date')
plt.ylabel('Appliances')

 

 

 

train, test split 및 추가 전처리
# 데이터 나누기
appliances=df[['Appliances']]
split_date = '2016-04-30 08:20:00'

#학습용 데이터와 테스트용 데이터로 분리
train_data=pd.DataFrame(appliances.loc[:split_date,['Appliances']])
test_data=pd.DataFrame(appliances.loc[split_date:,['Appliances']])

#분리된 데이터 시각화
fig = plt.figure(figsize=(25, 9))
ax = fig.add_subplot(111)
train_data.plot(ax=ax)
test_data.plot(ax=ax)
plt.legend(['train', 'test'])

  • 파란색은 train, 주황색은 test 셋으로 나누었다.

 

# 데이터 정규화

from sklearn.preprocessing import MinMaxScaler 
scaler = MinMaxScaler() 
train_data_sc=scaler.fit_transform(train_data)
test_data_sc= scaler.transform(test_data)
#학습 데이터와 테스트 데이터( ndarray)를 데이터프레임으로 변형한다.
train_sc_df = pd.DataFrame(train_data_sc, columns=['Scaled'], index=train_data.index)
test_sc_df = pd.DataFrame(test_data_sc, columns=['Scaled'], index=test_data.index)
# 데이터 윈도우 생성

for i in range(1, 19):
    train_sc_df ['Scaled_{}'.format(i)]=train_sc_df ['Scaled'].shift(i)
    test_sc_df ['Scaled_{}'.format(i)]=test_sc_df ['Scaled'].shift(i)
train_sc_df

 

#nan 값이 있는 로우를 삭제하고 X값과 Y값을 생성한다.
x_train=train_sc_df.dropna().drop('Scaled', axis=1)
y_train=train_sc_df.dropna()[['Scaled']]

x_test=test_sc_df.dropna().drop('Scaled', axis=1)
y_test=test_sc_df.dropna()[['Scaled']]
#대부분의 기계학습 모델은 데이터프레임 대신 ndarray구조를 입력 값으로 사용한다.
#ndarray로 변환한다.

x_train=x_train.to_numpy()
x_test=x_test.to_numpy()

y_train=y_train.to_numpy()
y_test=y_test.to_numpy()

print(x_train.shape)
print(x_test.shape)
print(y_train.shape)
print(y_test.shape)

 

 

 

LSTM 모델 생성
#LSTM 모델에 맞게 데이터 셋 변형
x_train_t = x_train.reshape(x_train.shape[0], 18,1)
x_test_t = x_test.reshape(x_test.shape[0], 18, 1)
from tensorflow.keras.layers import LSTM 
from tensorflow.keras.models import Sequential 
from tensorflow.keras.layers import Dense 
import tensorflow.keras.backend as K 
from tensorflow.keras.callbacks import EarlyStopping
K.clear_session() 
# Sequeatial Model
model = Sequential() 
# 첫번째 LSTM 레이어
model.add(LSTM(30,return_sequences=True, input_shape=(18, 1))) 
# 두번째 LSTM 레이어
model.add(LSTM(42,return_sequences=False))  
# 예측값 1개
model.add(Dense(1, activation='sigmoid')) 
# 손실함수 지정 - 예측 값과 실제 값의 차이를 계산한다. MSE가 사용된다. 
# 최적화기 지정 - 일반적으로 adam을 사용한다.
model.compile(loss='mean_squared_error', optimizer='adam') 
model.summary()

 

#손실 값(loss)를 모니터링해서 성능이 더이상 좋아지지 않으면 epoch를 중단한다.
#vervose=1은 화면에 출력
early_stop = EarlyStopping(monitor='loss', patience=5, verbose=1)
#epochs는 훈련 반복 횟수를 지정하고 batch_size는 한 번 훈련할 때 입력되는 데이터 크기를 지정한다.
model.fit(x_train_t, y_train, epochs=50,
          batch_size=20, verbose=1, callbacks=[early_stop])

y_pred = model.predict(x_test_t)

 

# 예측값과 실제값 비교

t_df=test_sc_df.dropna()
y_test_df=pd.DataFrame(y_test, columns=['Appliances'], index=t_df.index)
y_pred_df=pd.DataFrame(y_pred, columns=['Appliances'], index=t_df.index)


fig = plt.figure(figsize=(25, 9))
ax1 = fig.add_subplot(111)
y_test_df.plot(ax=ax1)
y_pred_df.plot(ax=ax1)
plt.legend(['test','pred'])

 

  • 실제값과 예측값을 비교해봤을 때 어느 정도 잘 예측한 것을 알 수 있다.