1. 문제 정의 & 데이터 다운
-독일 예나 시에 있는 막스 플랑크 생물지구화학 연구소의 지상 관측소 수집 데이터
-14개의 관측치 데이터가 10분마다 기록되어 있음(2009~2016 데이터를 활용)
#데이터 살펴보기
import os
data_dir = 'C:/Users/82109/Desktop/example' #다운받은 폴더 경로 설정
fname = os.path.join(data_dir, 'jena_climate_2009_2016.csv') #파일 경로 설정
f = open(fname) # r, w, a 모드가 존재
data = f.read()
f.close()
print(type(data)) #str 형식으로 데이터가 저장되어 있다.
#CSV 파일 형식 행은 "콤마" 로 열을 "\n"으로 나눠서 저장되어있다.
lines = data.split('\n')
header = lines[0].split(',')
lines = lines[1:]
print(header)
# ['"Date Time"', '"p (mbar)"', '"T (degC)"', '"Tpot (K)"', '"Tdew (degC)"', '"rh (%)"',
#'"VPmax (mbar)"', '"VPact (mbar)"', '"VPdef (mbar)"', '"sh (g/kg)"', '"H2OC (mmol/mol)"', '"rho (g/m**3)"', '"wv (m/s)"', '"max. wv (m/s)"', '"wd (deg)"']
print(len(lines))
#420551
csv파일을 열고 데이터 구조를 파악할 필요가 있다.
연산속도를 빠르게 하기 위해서 numpy로 변환해준다.
2. NUMPY로 변환해주기 & 살펴보기
import numpy as np
float_data = np.zeros((len(lines), len(header) - 1)) #빈 어레이 형성
for i, line in enumerate(lines):
values = [float(x) for x in line.split(',')[1:]] #값 저장
float_data[i, :] = values #이렇게도 되네..
numpy로 변환시켜줄 때, 열을 한번에 바꿔주면 이중포문보다 훨씬 시간이 적게 소요 될것 같다.
from matplotlib import pyplot as plt
temp = float_data[:, 5] # 온도(섭씨)
plt.plot(range(len(temp)), temp)
plt.show()
float_data[ : , 숫자] 에서 숫자를 바꿔주면 각각 변수에 대한 그래프를 확인 할 수 있다.
주기성을 갖는 것을 볼 수 있다. 이후에, 크기를 줄여서 하루 데이터 이런식으로 볼 수 있는데, 코드는 생략하겠다.
3. 데이터 준비하기
사전작업으로 두가지를 진행합니다.
첫 번째는 데이터 정규화 입니다. 이미 숫자 형태의 넘파이로 바꿔서, 형변환은 필요하지 않지만, 각 변수들마다 편차가 심해 비슷한 크기로 정규화를 진행합니다. (평균을 빼고 표준편차로 나누는 작업으로 진행합니다)
mean = float_data[:200000].mean(axis=0)
float_data -= mean
std = float_data[:200000].std(axis=0)
float_data /= std
print(float_data)
-1 ~ 1 비슷한 숫자들로 정규화 된것을 확인 할 수 있다.
두번쨰는 파이썬 제너레이터 생성 입니다. yield를 이용하여 튜플 형식으로 반복전으로 return 한다고 볼 수 있다.
sample 에는 고려하는 다양한 파라미터 데이터들, target에는 목표로 하는 온도가 들어가 있다.
#제너레이터 형성
def generator(data, lookback, delay, min_index, max_index,
shuffle=False, batch_size=128, step=6):
if max_index is None:
max_index = len(data) - delay - 1 #max_index에 대한 정보가 없으면 끝을 max로 설정
i = min_index + lookback
while 1: #반복적으로 yield출력
if shuffle: #범위 안에서 배치 수 만큼 임의 추출
rows = np.random.randint(min_index + lookback, max_index, size=batch_size)
else:
#max넘어가면 처음으로 돌리는 if문
if i + batch_size >= max_index:
i = min_index + lookback
#순서대로 rows에 batch_Size만큼 채워넣기
rows = np.arange(i, min(i + batch_size, max_index))
i += len(rows)
#sample은 (128,240,14) = (배치사이즈, 고려하는 타임스탭의 수 ,파라미터 수)
samples = np.zeros((len(rows),
lookback // step,
data.shape[-1]))
#targets 는 배치 사이즈
targets = np.zeros((len(rows),))
for j, row in enumerate(rows):
indices = range(rows[j] - lookback, rows[j], step)
samples[j] = data[indices]
targets[j] = data[rows[j] + delay][1] #온도 변수
yield samples, targets
4. 초기값 설정 및 생성
lookback = 1440 #10전 데이터를 활용하겠다는 의미
step = 6
delay = 144
batch_size = 128
train_gen = generator(float_data,
lookback=lookback,
delay=delay,
min_index=0,
max_index=200000,
shuffle=True,
step=step,
batch_size=batch_size)
val_gen = generator(float_data,
lookback=lookback,
delay=delay,
min_index=200001,
max_index=300000,
step=step,
batch_size=batch_size)
test_gen = generator(float_data,
lookback=lookback,
delay=delay,
min_index=300001, #끝을 모를 수 도 있으니까 사용
max_index=None,
step=step,
batch_size=batch_size)
# 전체 검증 세트를 순회하기 위해 val_gen에서 추출할 횟수
val_steps = (300000 - 200001 - lookback) // batch_size
# 전체 테스트 세트를 순회하기 위해 test_gen에서 추출할 횟수
test_steps = (len(float_data) - 300001 - lookback) // batch_size
5. 기본 모델 생성 및 실행
from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop
model = Sequential()
model.add(layers.GRU(32, input_shape=(None, float_data.shape[-1])))
model.add(layers.Dense(1))
model.compile(optimizer=RMSprop(), loss='mae')
history = model.fit_generator(train_gen,
steps_per_epoch=500,
epochs=20,
validation_data=val_gen,
validation_steps=val_steps)
케라스 창시자에게 배우는 딥러닝의 예제이다. LSTM을 공부할때 input shape에 3가지에 대해서 감을 잡기 좋은
예제 인것 같다.
'Data Science > Examples' 카테고리의 다른 글
[딥러닝 기초] Kaggle 연습 문제 Melbourne house pricing (0) | 2020.08.04 |
---|
댓글