본문 바로가기
Project

[ 환경방사선 예측 프로그램 ] 3. LSTM 모델 활용하여 예측하기

by Foxy현 2023. 3. 8.
728x90
반응형

오늘은 LSTM(Long Short-Term Memory) 모델을 사용하여 선량률(nSv/h)을 예측하는 프로그램을 만들어볼 것입니다.

LSTM은 RNN(Recurrent Neural Network)의 일종으로, 시계열 데이터를 처리할 때 유용합니다.

이 모델은 과거의 데이터를 바탕으로 미래 값을 예측하는 데 사용되므로 이전 날짜들의 데이터가 필요합니다.

 


1. 필요한 라이브러리 import

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
import tensorflow as tf
from keras.layers import Dense, LSTM

 

2. 데이터 불러오기

df = pd.read_csv('data/df.csv', encoding='utf-8')

 

3. 데이터 전처리

df['강수량(mm)'].fillna(0, inplace=True)
df['기온(°C)'] = df['기온(°C)'].astype(float)
df['강수량(mm)'] = df['강수량(mm)'].astype(float)
df['현지기압(hPa)'] = df['현지기압(hPa)'].astype(float)

데이터 전처리를 위해 각 column의 데이터 타입을 변경해줍니다.

df['기온(°C)'] = df['기온(°C)'].astype(float)과 같은 형태로, astype() 함수를 사용하여 각 column의 데이터 타입을 float으로 변경합니다.

또한, 결측값이 포함된 column인 '강수량(mm)'에 대해서는 df['강수량(mm)'].fillna(0, inplace=True)를 사용하여 0으로 채워주었습니다.

 

# X 데이터프레임에서 year, month, day, hour 열을 추가한 후 drop하지 않은 경우
X = df[['일시', '기온(°C)', '강수량(mm)', '현지기압(hPa)']]
X['일시'] = pd.to_datetime(X['일시']) 
X['year'] = X['일시'].dt.year
X['month'] = X['일시'].dt.month
X['day'] = X['일시'].dt.day
X['hour'] = X['일시'].dt.hour
X = X.drop('일시', axis=1)
# year, month, day, hour 열을 제외한 feature들만 선택하여 MinMaxScaler를 적용

이때, X에는 일시 열과 함께 기온, 강수량, 현지기압 데이터가 저장됩니다.

다음으로, 일시 열을 pandas의 to_datetime 함수를 이용하여 날짜와 시간으로 변환합니다.

 

X_for_scaler = X.drop(['year', 'month', 'day', 'hour'], axis=1)  # year, month, day, hour 열 제외
scaler = MinMaxScaler(feature_range=(0, 1))
X_for_scaler = scaler.fit_transform(X_for_scaler)

feature scaling을 위해, sklearn.preprocessing 라이브러리의 MinMaxScaler 함수를 사용합니다. MinMaxScaler(feature_range=(0, 1))와 같이 함수를 호출하여 feature scaling을 수행합니다.

 

4. 학습 데이터와 타깃 데이터 정의

# 스케일링한 feature들을 X 데이터프레임에 다시 추가
X[['기온(°C)', '강수량(mm)', '현지기압(hPa)']] = X_for_scaler
Y = df[['선량률(nSv/h)']]

 

5. LSTM 모델 생성

# LSTM 모델 구성
model = Sequential()
model.add(LSTM(128, input_shape=(X.shape[1], 1)))
model.add(Dense(1))

LSTM 모델을 구성하기 위해서는 Sequential 클래스를 사용합니다.

model = Sequential()으로 모델을 생성한 후, model.add(LSTM(128, input_shape=(X.shape[1], 1)))과 같이 LSTM 레이어를 추가합니다.

여기서 128은 뉴런의 개수를 나타내며, input_shape=(X.shape[1], 1)은 입력 데이터의 형태를 나타냅니다.

그리고 model.add(Dense(1))과 같이 Dense 레이어를 추가합니다.

이 Dense 레이어는 LSTM 레이어의 출력을 입력으로 받아들이고, 출력값을 1차원으로 반환합니다.

 

6. 모델 학습

# 모델 컴파일
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])

# 모델 학습
model.fit(X, Y, epochs=50, batch_size=1, verbose=2)

모델을 컴파일하는 단계에서는 compile() 함수를 사용하여 모델이 사용할 손실 함수(loss function), 옵티마이저(optimizer), 평가 지표(metrics)를 정의합니다.

 

7. 모델 평가

# 모델 평가
train_score = model.evaluate(X, Y, verbose=0)
print('Train Score: %.2f MSE (%.2f RMSE)' % (train_score[0], np.sqrt(train_score[0] ** 2)))

마지막으로 모델을 평가합니다. 

 

8. 예측

# 새로운 데이터로 예측
new_X = np.array([[0.3, 0.2, 0.4, 2023, 3,2,3]])
new_X_for_scaler = new_X[:, :-4]  # year, month, day, hour 열 제외
new_X_for_scaler = scaler.fit_transform(new_X_for_scaler)
new_X[:, :-4] = new_X_for_scaler

# new_X의 shape를 (1, 7, 1)로 변환
new_X = np.reshape(new_X, (new_X.shape[0], new_X.shape[1], 1))
new_Y = model.predict(new_X)
new_Y = scaler.inverse_transform([[new_Y[0][0], new_Y[0][0], new_Y[0][0]]])
print('Predicted value: %.2f' % new_Y[0][0])

 

test 데이터 인풋으로는 기온, 강수량, 현지기압, year, month, day, hour 순으로 입력하면 위와 같은 예측 값이 나오게 됩니다.

Hola

728x90
반응형