overview

deep learning
공개

2025년 12월 18일

모델

  • 단일 단계 모델: 한 대상에 대한 한 시간 단계 예측
  • 다중 단계 모델: 한 대상에 대한 여러 시간 단계 예측을 생성
  • 다중 출력 모델: 여러 대상에 대한 여러 시간 단계 예측을 생성

Example

import pandas as pd
df = pd.read_csv("data/traffic.csv")
df.head()
date_time temp rain_1h snow_1h clouds_all traffic_volume
0 2016-09-29 17:00:00 291.75 0.0 0 0 5551.0
1 2016-09-29 18:00:00 290.36 0.0 0 0 4132.0
2 2016-09-29 19:00:00 287.86 0.0 0 0 3435.0
3 2016-09-29 20:00:00 285.91 0.0 0 0 2765.0
4 2016-09-29 21:00:00 284.31 0.0 0 0 2443.0
import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

ax.plot(df['traffic_volume'])
ax.set_xlabel('Time')
ax.set_ylabel('Traffic Volume')

plt.xticks(np.arange(7, 400, 24), ['Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'])
plt.xlim(0, 400)
fig.autofmt_xdate()
plt.tight_layout()

  • 일별 계절성: 하루의 시작과 긑에 교통량이 적음
  • 주간 계절성: 주말에 교통량이 적음
  • SARIMAX는 이러한 계절성이 여러개 있는 시계열 데이터를 모델링하는데 적합하지 않음
fig, ax = plt.subplots()

ax.plot(df['temp'])
ax.set_xlabel('Time')
ax.set_ylabel('Temperature (K)')

plt.xticks([2239, 10999], [2017, 2018])

fig.autofmt_xdate()
plt.tight_layout()

  • 기온 역시 연간 계절성을 가지고,
fig, ax = plt.subplots()

ax.plot(df['temp'])
ax.set_xlabel('Time')
ax.set_ylabel('Temperature (K)')

plt.xticks(np.arange(7, 400, 24), ['Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'])
plt.xlim(0, 400)
fig.autofmt_xdate()
plt.tight_layout()

  • 일별 계절성도 가지고 있다.
df.describe().transpose()
count mean std min 25% 50% 75% max
temp 17551.0 281.416203 12.688262 243.39 272.22 282.41 291.89 310.07
rain_1h 17551.0 0.025523 0.259794 0.00 0.00 0.00 0.00 10.60
snow_1h 17551.0 0.000000 0.000000 0.00 0.00 0.00 0.00 0.00
clouds_all 17551.0 42.034129 39.065960 0.00 1.00 40.00 90.00 100.00
traffic_volume 17551.0 3321.484588 1969.223949 113.00 1298.00 3518.00 4943.00 7280.00
  • 정보가 없는 강수량, 강설량은 제거
from datetime import datetime

df = df.drop(['rain_1h', 'snow_1h'], axis=1)
df['date_time'] = pd.to_datetime(df['date_time']).map(datetime.timestamp)
df
date_time temp clouds_all traffic_volume
0 1.475136e+09 291.75 0 5551.0
1 1.475140e+09 290.36 0 4132.0
2 1.475143e+09 287.86 0 3435.0
3 1.475147e+09 285.91 0 2765.0
4 1.475150e+09 284.31 0 2443.0
... ... ... ... ...
17546 1.538302e+09 283.45 75 3543.0
17547 1.538305e+09 282.76 90 2781.0
17548 1.538309e+09 282.73 90 2159.0
17549 1.538312e+09 282.09 90 1450.0
17550 1.538316e+09 282.12 90 954.0

17551 rows × 4 columns

  • 시간을 초 단위로 변환.
day = 24 * 60 * 60
df['day_sin'] = np.sin(df['date_time'] * (2 * np.pi / day))
df['day_cos'] = np.cos(df['date_time'] * (2 * np.pi / day))
df = df.drop(['date_time'], axis=1)
df
temp clouds_all traffic_volume day_sin day_cos
0 291.75 0 5551.0 8.660254e-01 -0.500000
1 290.36 0 4132.0 7.071068e-01 -0.707107
2 287.86 0 3435.0 5.000000e-01 -0.866025
3 285.91 0 2765.0 2.588190e-01 -0.965926
4 284.31 0 2443.0 1.485292e-12 -1.000000
... ... ... ... ... ...
17546 283.45 75 3543.0 5.000000e-01 -0.866025
17547 282.76 90 2781.0 2.588190e-01 -0.965926
17548 282.73 90 2159.0 2.467248e-12 -1.000000
17549 282.09 90 1450.0 -2.588190e-01 -0.965926
17550 282.12 90 954.0 -5.000000e-01 -0.866025

17551 rows × 5 columns

  • 단순 초 단위 변환은 주기적 패턴을 포착하지 못하기 때문에 사인 및 코사인 변환을 사용하여 일별 주기를 인코딩
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler

train, test = train_test_split(df, test_size=0.1, shuffle=False)
train, val = train_test_split(train, test_size=0.2, shuffle=False)

scaler = MinMaxScaler()
train_scaled = scaler.fit_transform(train)
val_scaled = scaler.transform(val)
test_scaled = scaler.transform(test)
train.to_csv("data/traffic_train.csv", index=False)
val.to_csv("data/traffic_val.csv", index=False)
test.to_csv("data/traffic_test.csv", index=False)
맨 위로