데이터 한 그릇

12) 시계열 RNN 본문

PaperReview

12) 시계열 RNN

장사이언스 2022. 11. 4. 10:25

지금까지 기본 ANN 과 CNN 을 활용한 시계열 예측을 시도해봤다

다음으로는 RNN 을 활용하여 시계열을 예측해보려고 한다


df = pd.read_csv('PRSA_data_2010.1.1-2014.12.31.csv')
print('Shape of the dataframe:', df.shape)
df.head()

 

마찬가지로 datetime 칼럼을 생성해야만한다

 

df['datetime'] = df[['year', 'month', 'day', 'hour']].\
    apply(lambda row: datetime.datetime(year=row['year'], \
    month=row['month'], day=row['day'],hour=row['hour']), axis=1)
df.sort_values('datetime', ascending=True, inplace=True)
df.head()

 

datetime.datetime 을 활용해서 마찬가지로 datetime 칼럼을 생성한다

 

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
df['scaled_PRES'] = scaler.fit_transform(np.array(df['PRES']).reshape(-1, 1))
df.head()

0~1사이의 값으로 minmaxscaler 해준다

 

split_date = datetime.datetime(year=2014, month=1, day=1, hour=0)
df_train = df.loc[df['datetime']<split_date]
df_test = df.loc[df['datetime']>=split_date]
print('Shape of train:', df_train.shape)
print('Shape of test:', df_test.shape)

 

df_test.reset_index(drop=True, inplace=True)

인덱스를 맞춰준다

 

def makeXy(ts, nb_timesteps):
    X = []
    y = []
    for i in range(nb_timesteps, ts.shape[0]):
        X.append(list(ts.loc[i-nb_timesteps:i-1]))
        y.append(ts.loc[i])
    X, y = np.array(X), np.array(y)
    return X, y
    
    
X_train, y_train = makeXy(df_train['scaled_PRES'], 7)
print('Shape of train arrays:', X_train.shape, y_train.shape)
print(X_train[0])
print(y_train[0])


X_test, y_test = makeXy(df_test['scaled_PRES'], 7)
print('Shape of Test arrays:', X_test.shape, y_test.shape)
print(X_test[0])
print(y_test[0])

 

마찬가지로 X,y 로 학습 데이터와 타겟 데이터를 넣어준다

 

from keras.layers import Dense, Dropout
from keras.layers.recurrent import LSTM
from keras.models import Sequential


X_train, X_test = X_train.reshape((X_train.shape[0], \
    X_train.shape[1], 1)), X_test.reshape((X_test.shape[0], X_test.shape[1], 1))
print('Shape of 3D arrays:', X_train.shape, X_test.shape)

CNN과 마찬가지로 tensorflow 가 기대하는 데이터 입력의 shape 이 있기 때문에 기대되는 shape 에 맞춰서 reshape 해준다

(2차원 -> 3차원)

 

model=Sequential()
model.add(LSTM(64,input_shape=(7,1)))
model.add(Dropout(0.2))
model.add(Dense(1, activation='linear'))

 

RNN 기반의 모델 중 LSTM 모델을 활용한다

Simple RNN 의 경우 장기 기억과 관련해서는 잘 처리하지 못하는 현상이 발생하며, 가중치가 소멸하는 문제가 발생한다

이러한 문제를 해결하기 위해서 LSTM 모델이 고안됐다

 

model.compile(loss='mean_squared_error', optimizer='adam')
model.summary()

 

손실함수로는 mean squared error, 최적화 방식으로는 adam 을 사용했다

 

history=model.fit(X_train, y_train, batch_size=16, epochs=10,shuffle=True)

preds = model.predict(X_test)
pred_PRES = scaler.inverse_transform(preds)
pred_PRES = np.squeeze(pred_PRES)

from sklearn.metrics import r2_score
r2 = r2_score(df_test['PRES'].loc[7:], pred_PRES)
print('R-squared for the test set:', round(r2,4))

plt.plot(range(50), df_test['PRES'].loc[7:56], linestyle='-', marker='*', color='r')
plt.plot(range(50), pred_PRES[:50], linestyle='-', marker='.', color='b')
plt.legend(['Actual','Predicted'], loc=2)
plt.title('Actual vs Predicted Air Pressure')
plt.ylabel('Air Pressure')
plt.xlabel('Index')

 

 

ANN과 CNN 과 마찬가지로 plot 을 그려서 확인해볼 수 있다

Comments