시계열 데이터 분석
KOSPI주가 정보를 저장한 시계열 데이터를 이용해서 정보를 분석하는 연습을 합니다. 시계열데이터 분석을 위해서 시간에 따라 이동시키거나 일정 주기로 추출하는 작업을 수행을 합니다. 일정 기간동안의 통계적 특성을 분석하기 위해서 window을 만들고 이동할 수도 있습니다.
우선 연습을 위해서 KOSPI주가 정보를 가져옵니다. KOSPI주가 정보를 가져오기 위해 FinanceDataReader
라이브러리를 사용합니다. DataReader
함수에 시계열 정보를 가져올 주식 종목 기호 KS11
과 시작 시점을 전달합니다.
#| label: fig-timeseries-kospi
#| fig-cap: "KOPI 시계열 데이터"
import pandas as pd
import numpy as np
import FinanceDataReader as fdr
= 'KS11'
stock_name = fdr.DataReader(stock_name, start = '2022-1-1')
df 5)) display(df.head(
리턴된 데이터를 간단하게 살펴봅니다. 시간 정보로 Index가 표시되고 주가 정보는 각 컬럼에 표시됩니다. 해당 시점의 고점
, 저점
, 종가
, 수정 종가
, 시가 총액
이 각각 컬럼으로 있습니다.
?@fig-timeseries-kospi 의 index의 데이터 형식은 DatetimeIndex
로 출력됩니다. 따라서 시계열 데이터 분석에 사용할 수 있는 Pandas 기능을 사용할 수 있습니다.
shift()
시간을 이동시키는 명령어인 shift()
함수를 알아봅니다. shift()함수는 지정한 수만큼 인덱스를 이동 시키는 명령입니다. ?@fig-timeseries-kospi 데이터 프레임은 한국 주식 시장이 운영기간을 하루 단위로 측정된 시계열 데이터 프레임입니다. shift()
명령을 이용하여 Close
컬럼 데이터를 1개 Index크기 만큼 앞으로 이동합니다.
'Close+1'] = df['Close'].shift(1)
df['Close', 'Close+1']].head(5)) display(df[[
비교를 쉽게하기 위해서 Close
와 Close+1
컬럼만 표시하여 결과를 확인합니다. 새롭게 생성한 Close+1
컬럼은 Close
컬럼이 이동되어 저장되었습니다. 정보를 가져올 수 없는 2023-01-02
인덱스 정보는 NaN
으로 표시됩니다.
asfreq()
시계열 데이터 프레임을 새로운 빈도로 변환하기 위해서 as_freq()
함수를 사용합니다. KOSPI주가 데이터의 월별 종가 정보를 확인할 수 있도록 이 함수를 사용해 봅니다.
= df.asfreq('M')
df_monthly 5)) display(df_monthly.head(
결과를 보면 NaN
으로 데이터가 처리된 부분이 있습니다. 2020년 1월 31일과 2022년 4월 30일 데이터는 왜 없는 걸까요?
= pd.Timestamp('2022-01-28 00:00:00')
start_day = start_day + pd.DateOffset(days = 10)
end_day df.loc[start_day : end_day, :]
시작일을 2022-01-28일로 설정하고 시작일로 부터 10일 간격 뒤의 시간을 종료일로 설정 후 해당 위치의 데이터 프레임 정보를 확인합니다. 1월의 마지막은 1월 31일이지만 주식시장은 1월 28일 거래로 폐장 후 2월에 개장하기 때문에 데이터가 없는 상태입니다.
asfreq()
로 간격을 설정한 기준은 월말을 기준으로 했기 때문에 해당 시점에 데이터가 없어 NaN
으로 결과가 출력 되었습니다.
새로운 시간 단위를 설정 시 새롭게 설정하는 시간간격에 맞는 원데이터가 없는 경우 NaN
으로 데이터가 표시되기 때문에 결과에 유의 해야합니다.
주식정보를 갖는 이 데이터 프레임의 특성 상 해당 날짜에 주가 정보가 없다면 직전 날짜의 주가 정보를 유지하면 될 것 같습니다. 1월 28일의 마지막 주가 정보를 1월말 주가 정보로 대체해도 문제가 없는 데이터이기 때문에 as_freq()
함수의 method
인자를 이용합니다.
method
인자에는 NaN
으로 표시된 결측치를 어떤 정보로 채울지 결정할 정보를 전달합니다. API문서를 확인하면 bfill
과 ffill
을 지원한다고 합니다. 우리의 경우 이전 시점의 데이터로 결측치를 채울 예정이니 ffill
로 설정합니다.
= df.asfreq('M', method='ffill')
df_monthly 5)) display(df_monthly.head(
이번에는 월말인 2022년 1월 31일 데이터가 NaN
이 아니고 이전 시점의 데이터로 업데이트 된 것을 알 수 있습니다.
resample()
resample()
함수는 주어진 빈도로 리샘플링할 때 사용합니다. 데이터를 보간하여 빈 시간대에 대한 새로운 값을 생성합니다. 시간을 기반으로 한 데이터에 적용하는 groupby
함수로 생각할 수 있습니다.
asfreq()
함수는 주기를 변경하기 위해 사용되어 해당 시점에 원데이터가 없다면 NaN
으로 표시됩니다.
= df.resample('M').last()
df_monthly 5) df_monthly.head(
resample()
함수에 시간 간격이 전달된 후 리턴되는 객체는 DatetimeIndexResampler
입니다. 이 객체에 시간단위로 그룹된 데이터를 처리할 방식을 전달합니다. 월단위로 리샘플링된 그룹에 마지막 값을 취하기 위해서 last()
를 수행하여 매월 마지막 주가정보로 저장되었습니다.
= df.resample('M').mean()
df_monthly 5) df_monthly.head(
KOSPI주가 지수의 월별 평균값을 구해봅니다. 시간간격은 동일하게 월 단위이고 해당 시간 단위 데이터를 평균하기 위해 mean
함수를 사용했습니다.
rolling()
시계열 정보에서는 여러가지 이동 통계를 사용합니다. 일반적으로 이동 평균
, 이동 표준 편차
등이 주로 사용됩니다. 이동 통계를 이용하면 시계열 데이터의 추세를 확인할 수 있으며 이상치 검출에도 사용할 수 있습니다. 이동 윈도우에 크기에 따라서 데이터를 부드럽게 만들 수 있기 때문에 데이터가 가지는 불필요한 고주파 노이즈를 제거할 수 있습니다.
Pandas에서는 rolling()
함수로 롤링 윈도우를 지원합니다. 이 함수를 이용해서 KOSPI 지수의 60일 이동평균값을 확인해봅니다.
= df.rolling('60d').mean()
df_monthly 5) df_monthly.head(