일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 플로틀리
- 짧은 시계열 # 금융시계열
- timeseries decomposition
- stl
- 시계열시각화
- 시계열모듈
- loess
- 파이프라인전처리
- 크롤링자동화
- 빈 데이터프레임 #pandas #데이터전처리
- 년월일 데이터
- 리눅스개념
- seaborn # kdeplot # 데이터분석
- 시계열
- pandas
- 응용이 보이는 선형대수
- adf_test
- 시간형식
- 시간형식변환
- Python
- 음수값 #전처리 #선형보간 #pandas #데이터 #데이터분석
- np.split
- 시계열분해
- 시계열 #reindex #인덱스 확장 #datetime index #index extention # 데이터전처리
- 날짜파싱
- 시계열데이터셋
- 이수역 양식집
- 확률
- 오제이튜브
- pandas # 월말 날짜 # 마지막 주 # 날짜계산 # 시계열 # 마지막 주 금요일
- Today
- Total
데이터분석과 개발
[전처리] 시계열 데이터에서 train, validation, test 나누기 본문
* 공부한 것을 정리한 글이므로 틀린 내용이 있을 수 있습니다.
* 더 좋은 방법 또는 틀린부분이 발견될 시 계속 수정하며 업데이트 할 예정입니다.
오늘은 train, validation, test 데이터셋을 나누는 방법에 대해 포스팅 해보려 합니다.
일반적인 분류, 회귀 모델과 달리 시간의 흐름을 지켜줘야 하기 때문에 어떻게 보면 더 어렵기도 하고 더 쉽기도 한 것 같습니다.
darts 데이터셋에 있는 'Daily minimum Temperature' 데이터를 사용하여 train validation test 를 나눠보겠습니다.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from darts.datasets import TemperatureDataset
sns.set_context('talk')
df = TemperatureDataset().load().pd_dataframe()
# 5년치 최저온도 데이터셋
df = df.loc[:'1985']
df
1. 날짜 구간별 나누기
정확한 날짜 구간이 필요하다면 인덱스에 datetime형식의 날짜를 넣고 df.loc[시작날짜: 끝날짜] 를 쓰면 좋습니다.
이때 여러가지 날짜 구하는 모듈이 있지만 저의 경우 dateutil 의 relativedelta 함수를 자주 사용하고 있네요.
각 구간의 날짜를 직접 계산해줘야 합니다.
(상당히 번거롭습니다 더 좋은 방법 아시는 분 댓글 달아주시면 감사하겠습니다)
train 3년, validation 1년, test 1년으로 나눠주겠습니다.
굳이 다 계산을 해주는 이유는 처음 시작날짜만 바꾸면 자동으로 3년,1년,1년이 나눠질 수 있게 하기 위함입니다.
from dateutil.relativedelta import relativedelta
## train: 1981년부터 3년
train_start_date = '1981-01-01'
train_end_date = str(pd.to_datetime(train_start_date)
+ relativedelta(years=3)
- relativedelta(days=1))[:10]
print("train 기간: ",f"{train_start_date}~{train_end_date}")
## validation: 1984년부터 1년
valid_start_date = str(pd.to_datetime(train_end_date)
+ relativedelta(days=1))[:10]
valid_end_date = str(pd.to_datetime(train_end_date)
+ relativedelta(years=1) )[:10]
print("valid 기간: ",f"{valid_start_date}~{valid_end_date}")
## test: 1985년부터 1년
test_start_date = str(pd.to_datetime(valid_end_date)
+ relativedelta(days=1))[:10]
test_end_date = str(pd.to_datetime(valid_end_date)
+ relativedelta(years=1))[:10]
print("test 기간: ",f"{test_start_date}~{test_end_date}")
# train, validation, test split
df_train = df.loc[train_start_date:train_end_date]
df_validation = df.loc[valid_start_date:valid_end_date]
df_test = df.loc[test_start_date:test_end_date]
나눠진 결과를 보면 아래와 같은 기간으로 나눠지게 됩니다.
나눠진 데이터프레임을 보면 잘 나뉘어진 것을 볼 수 있습니다.
2. 데이터 개수별 나누기 : np.split()
만약 데이터비율 혹은 데이터개수(ex.1년 365일) 로 나눠도 상관없다면
np.split() 을 추천합니다.
# np.split() 사용법
# 데이터갯수가 200개인 df 를 150, 50개의 데이터프레임으로 나누려 한다면
df1, df2 = np.split(df, [150])
# 데이터갯수가 200개인 df 를 100, 50, 50개의 데이터프레임으로 나누려 한다면
df1, df2, df3 = np.split(df, [100, 150])
함수 안에 나눠줄 데이터프레임, 데이터 개수만 넣어주면 바로 나눠줄 수 있습니다.
# Train 4년 test data 1년
df_Train, df_test = np.split(df, [len(df)-365])
# train 3년, validation, test 를 각각 1년(365개씩)
df_train, df_validation, df_test = np.split(df, [len(df)-365*2, len(df)-365])
np.split()함수가 간단한 대신 1년이 365일이 확실한지 확인해야 한다는 단점이 있습니다.
1984년의 경우 윤년이기 때문에 1984년 1월1일이 제외된 모습을 보실 수 있습니다.
잘 나뉘어 졌는지 시각화로도 확인해보겠습니다.
fig, axs = plt.subplots(nrows=2, figsize=(10,5), constrained_layout=True)
axs[0].plot(df_train.index, df_train['Daily minimum temperatures'], label='train')
axs[0].plot(df_validation.index, df_validation['Daily minimum temperatures'], label='validation')
axs[0].plot(df_test.index, df_test['Daily minimum temperatures'], label='test')
axs[0].set_title("train validation test split")
axs[0].legend()
axs[1].plot(df_Train.index, df_Train['Daily minimum temperatures'], label='Train')
axs[1].plot(df_test.index, df_test['Daily minimum temperatures'], label='test')
axs[1].legend()
지금까지 train validation test 를 나누는 방법에 대해 포스팅 해보았습니다.
기회가 된다면 시계열 검증방법에 대해서도 공부하고 정리해보겠습니다.
감사합니다.
'AI(시계열) > 데이터 전처리' 카테고리의 다른 글
[Pandas] 년,월,일 따로 있는 데이터 읽기 : parse_dates, date_parser, index_col (0) | 2023.01.08 |
---|---|
[전처리] 전처리 파이프라인 구축하기(1) (0) | 2023.01.07 |
[Pandas] 시간데이터 전처리: datetime타입 형식변환 & 시간 차이 구하기 (0) | 2023.01.02 |
[Pandas] 원하는 데이터타입 컬럼 추출하기: df.dtypes, df.select_dtypes (0) | 2023.01.01 |