들어가기 전에-> 1. LSTM의 기본 개념은 타 블로그 글을 참고하면 될거같습니다.
2 . 개념은 알지만 코드를 짜는 부분에 있어서 햇갈리는 분들을 위한 글 입니다.
3.window Size 만드는 방법이 메인이 되는 게시글 입니다.
1. Window Size 만드는 방법.
( 그렇다 전처리는 중요한 과정이지만 사실상 전처리를 하는 방법은 자신의 판단에 의해 하는 것이고
원하는 전처리는 인터넷에 찾아보면 상당히 많은 글들이 있다.
즉, window size를 만드는 방법에 대해서 설명을 하겠다.)
# 데이터 셋을 만드는 함수
def make_dataset(data, label, window_size):
feature_list = []
label_list = []
for i in range(len(data) - window_size):
feature_list.append(np.array(data.iloc[i:i+window_size]))
label_list.append(np.array(label.iloc[i+window_size]))
return np.array(feature_list), np.array(label_list)
<설명>
(line별로 설명하겠습니다.)
line 1: 함수의 입력 인자로는 data ,label,window_size 가 들어감.
data : data 의 형식은 pandas.DataFrame의 형태로 들어와야하고 feature (=attribute =x값)가
입력되는 곳.
label: label 의 형식은 pandas.DataFrame의 형태로 들어와야하고 Class(=y값) 가 입력되어야 하는 곳.
window_size: 본인이 설정하고 싶은 window_size
line 2,3 : 비어있는 feature 리스트와 , 비어있는 label 리스트.
line 4 :for 문을 통해서 비어있는 리스트 안에 테이터를 넣기 위함 입니다.
(설명이 좀 난해하니 뒤에 까지 읽어보면 이해 되실겁니다.)
(솔직히 line4 이해 못해도 그닥(?) 상관없음.)
line 5 : 비어있는 feature_list에 window size만큼 자른후 np.array형태로 변환후,
뭉텅이씩 리스트에 넣어(append)주는 작업입니다.
( ☞ 이해를 돕기위해 자료를 직접 보시죵_이렇게 추가가 되는구나 느낌만 아시면 됩니다.)
1.현재 데이터의 모습
(저의 데이터는 8열이 label , 9열이 feature 입니다. (feature 한개입니다.))
2. DODI_C_20_5데이터의 1행(=파이썬0행)부터 20행(=파이썬19행)까지의 모습입니다.
3. feature와 label 이라는 데이터로 분리 해줌.
4. 현재 window_size =5
(window_size에 맞게 잘라서 5개씩 묶어서 다음꺼 하나를 예측할것입니다.)
[91]= 빈리스트
[92] = window_size =5 , i=0일떄의 모습
[93] = window_size =5 , i=1일떄의 모습
(2번의 사진과 비교해서 숫자를 보면 이해가 편합니다.)
5. 함수의 return 형태 (3차원임.)
line 6 : 비어있는 label_list에 window size만큼 자른후 np.array형태로 변환후,
뭉텅이씩 리스트에 넣어(append)주는 작업입니다.
(line5를 이해했다면 쉽게 이해할 수 있습니다.) ,(2차원임)
2. Window Size 결론.
9행에 보이는것처럼 window_size 만큼으로 묶어서 학습을 시키는것이다.
(과거의 5개(window_size)의 데이터를 가지고 예측을 함.) -> 과거5일치로 6일치(다음날)를 예측함.
(window_size=5일때 모습 , 9열=feature ,8행=label ,(현재 feature는 9행 한개임)
(나는 머리가 안좋은가... 이렇게 글로 쓰다보니 생각보다 어렵지 않다는게 확 와닫는다.. window_size 설코드찼던...고생했던기억이..)
3. 전체코드
1. 모듈 필요한거 쓰자. (자세한 전처리 과정은 코드에서 생략합니다.)
import pandas as pd # pandas 모듈
import numpy as np # numpy 모듈
from sklearn.model_selection import train_test_split # 훈련데이터 테스트 데이터 분류
from keras.layers import Dense, Conv1D ,Dropout , MaxPool1D ,LSTM
from keras.models import Sequential
from keras.callbacks import EarlyStopping, ModelCheckpoint
2. 엑셀 데이터 및 약간의 전처리 방법은 생략함. (랩실 과제이며 파일명 수정하고 등등의 이유..)
3. 데이터 셋을 만드는 함수
# 데이터 셋을 만드는 함수
def make_dataset(data, label, window_size):
feature_list = []
label_list = []
for i in range(len(data) - window_size): # for i in range(0:3712)
feature_list.append(np.array(data.iloc[i:i+window_size])) # np.array=values= pd dataframe을 np형식으로 바꿔줌.
label_list.append(np.array(label.iloc[i+window_size]))
return np.array(feature_list), np.array(label_list)
4. Train 데이터의 데이터셋을 만들고
feature와 label을 분류 하고
overfitting을 방지해보자.
## ' DODI_C_20_5 ' = Train DATA
# feaure, label 분류
## train_test_split 사용 (overfitting 방지)
DODI_C_20_5=np.array(DODI_C_20_5) #슬라이싱을 하기위해 np.array 형식으로 바꿈.
DODI_C_20_5_feature=pd.DataFrame(DODI_C_20_5[:,1]) # feature 열 추출
DODI_C_20_5_label=pd.DataFrame(DODI_C_20_5[:,0]) # label 열 추출
DODI_C_20_5_feature, DODI_C_20_5_label=make_dataset(DODI_C_20_5_feature,DODI_C_20_5_label,5) #window_size=5 설정
x_train, x_valid, y_train, y_valid = train_test_split(DODI_C_20_5_feature,DODI_C_20_5_label, test_size=0.2 , random_state=34)
x_train.shape, x_valid.shape,
(2981, 5, 1), (746, 5, 1)
5. TEST 데이터의 데이터셋을 만들고
feature와 label을 분류 하자
#### ' DODI_C_20_6 ' = TEST DATA
DODI_C_20_6=np.array(DODI_C_20_6) #슬라이싱을 하기위해 np.array 형식으로 바꿈.
DODI_C_20_6_feature = pd.DataFrame(DODI_C_20_6[:,1])
DODI_C_20_6_label = pd.DataFrame(DODI_C_20_6[:,0])
DODI_C_20_6_feature.shape
test_feature, test_label = make_dataset(DODI_C_20_6_feature, DODI_C_20_6_label, 5)
test_feature.shape, test_label.shape
(3711, 20, 1), (3711, 1)
6. model 설계. (LSTM의 activation 함수는 tanh가 되어야함.!! 어떤 예시들은 relu쓰던데.....)
-> LSTM의 input_shape=(time_step=window_size ,feature 개수)
model = Sequential()
# LSTM의 hidden layer가 16개 생김.
model.add(LSTM(16,
input_shape=(DODI_C_20_5_feature.shape[1], DODI_C_20_5_feature.shape[2]), #input shape=(time_step=windowsize,featrue개수)
activation='tanh',
return_sequences=False)
)
model.add(Dense(1))
model.summary()
7. model 컴파일
model.compile(loss='mean_squared_error', optimizer='adam',metrics="accuracy")
early_stop = EarlyStopping(monitor='val_loss', patience=100)
model.fit(x_train, y_train,
epochs=1000,batch_size=100,
validation_data=(x_valid, y_valid),
callbacks=[early_stop])
8. 시각화로 비교해보기
import matplotlib.pyplot as plt
pred = model.predict(test_feature)
plt.figure(figsize=(12, 9))
plt.plot(test_label, label = 'actual')
plt.plot(pred, label = 'prediction')
plt.legend()
plt.show()
이러한 결과가 나온다는것을 알 수 있다...
<햇갈릴것 같은 부분 예상.>
☞ 내가 LSTM을 구현하면 햇갈렸던 부분은 shape 였는데 왜이렇게 햇갈려했지...
1. LSTM layer에 들어가는
input_shape =(time_step ,feature 개수) 이고
input_shape =(window_size ,feature 개수) 와 동일한 의미이다.
2. feature 데이터 가공은 3차원으로 reshape 되어야 한다.
label 데이터 가공은 2차원으로 reshape되어야 한다.
즉 model.predict( ) 에서 ( ) 안에 들어가는 데이터는 3차원으로 reshape을 하여 가공하여 들어가야한다.
즉. model.fit(x_train, y_train ,....) 이 될텐데. x_train 은 3차원 y_train 은 2차원 이 되어야한다.
※ ex1) x_train.shape = (2981,5,1) y_train.shape = (2981,1)
input_shape(5,1)
ex2) x_train.shape = (4030,20,4) y_train.shape = (4030,4)
input_shape(20,4)
ex3) x_train.shape = (n,a,b) y_train.shape = (n,b)
input_shape(a,b)
->쉽게 말하면 feature데이터 가공한것(=x_train)의 1,2번 인덱스 값이 들어가면 된다.
3. 학습시킬 데이터들의 길이가 다르다면 패딩 또는 제거를 통해 길이를 맞춰주어야 합니다.
'인공지능 (기본 딥러닝) > 딥러닝 사이드 Project' 카테고리의 다른 글
[트랜스포머] 트랜스포머 인코더를 이용한 시계열 예측. (2) | 2023.07.13 |
---|---|
[CNN-Tensorflow] 커스텀 데이터 활용 이미지 분류 예제 코드 설명 (5) | 2023.02.26 |
YOLOv5 커스텀 데이터셋으로 학습하기 (27) | 2022.11.04 |
[CNN] Conv1D 커널(필터) 작동 방식 설명 (시계열 데이터 비교) (0) | 2022.09.02 |
[CNN] 예제 코드 설명 (회귀 예측 ,첫 번째 layer Conv1D사용) (0) | 2022.08.26 |