-
시계열 분석 시리즈 II (Plots, Decomposition, Autocorrelation)데이터 2024. 3. 3. 22:41
Time Plot
Time Plot은 시간의 흐름에 따라 데이터가 어떻게 변하는지를 보여주는 그래프다. 이는 시계열 데이터의 전반적인 패턴을 파악하는 데 유용하다. 데이터가 시간에 따라 증가하거나 감소하는지, 또는 주기적인 패턴이 있는지 등을 확인하기 위해 맨 처음 그려서 확인한다. tsibble 객체는 autoplot() 함수를 이용하여 Time Plot을 그린다. vic_elec를 이용하여 호주 빅토리아 주의 전기 수요량 Time Plot을 그려보자.
vic_elec %>% autoplot(Demand)
주기가 30분 간격인 데이터라서 과도하게 촘촘해보인다. 이번에는 일일 단위로 조정한 데이터를 만들어 동일한 Timp Plot을 그려보자.
vic_elec_day <- vic_elec %>% mutate(Day = as_date(Time)) %>% index_by(Day) %>% summarise(Demand_day = sum(Demand)/1000, # 단위 조정 Max_tmp = max(Temperature), # 그날의 최고기온으로 설정 Holiday = any(Holiday)) # 하나라도 TRUE 면 그날을 TRUE로 vic_elec_day %>% autoplot(Demand_day)
물론 아래와 같이 ggplot()과 geom_line 함수를 사용해도 Time Plot을 그려도 동일하다. 다만 autoplot()함수가 간편하여 사용하는 것이다.
vic_elec_day %>% ggplot(aes(x=Day, y = Demand_day )) + geom_line()
tourism 데이터는 24,320개 관측치를 갖는 주기가 분기[1Q]인 tsibble 객체이다. tourism 데이터에는 Key가 Region, State, Purpose로 총 304가지 다른 시계열 데이터가 들어있다. 이중 Victoria 주의 Melourne지역을 방문하는 여행객의 방문 목적별 데이터로 Time Plot을 그려보자. 여행 목적별로 구분해서 보려면 Key인 Purpose 변수의 범위를 한정하지 않으면 된다.
tourism %>% filter(Region == "Melbourne" & State == "Victoria" ) %>% autoplot(Trips)
시계열 패턴
추세(trend)
데이터가 장기적으로 증가하거나 감소할 때, 추세(trend)가 존재한다고 한다. 추세는 선형적일 필요는 없다.계절성(seasonality)
해마다 어떤 특정한 시기나 주일마다 특정 요일에 일정하게 나타나는 것 같은 패턴을 계절성(seasonality)이라고 한다. 계절성은 고정되어 있고 주기가 알려져 있다.주기성(cycle)
고정된 주기가 아닌 형태로 증가나 감소하는 패턴을 보일 때 주기성(cycle)이라고 한다. 계절성이 주기가 일정하다면 주기성은 주기가 일정하지 않은 특성이 있다.이전 시리즈에서 사용한 호주의 처방전 데이터인 PBS 데이터 중 ACT가 “A10” (Antidiabetic drug) 인 데이터만 발췌하여 추세와 계절성, 주기성에 대해 확인해 보자. 아래 Time Plot을 보자.
A10 <- PBS %>% filter(ATC2 == "A10") %>% select(Month, Concession, Type, Cost) %>% summarise(TotalC = sum(Cost)) %>% mutate(Cost = TotalC/1e6) A10 %>% autoplot(Cost) + labs(y = "호주$ (백만불)", title = " Antidiabetic drug 판매 Time Plot ")
1991년 7월부터 2008년 6월까지의 데이터를 살펴보면 크게 두 가지 특징을 확인 할 수 있다. 첫째, 약 구매 비용의 크기와 증감의 진폭이 해가 갈수록 더 커지고 있다는 점과 둘째, 약 구매 비용의 증감이 일정한 주기로 반복하고 있다는 점이다. 전자를 추세성(trend) 후자를 계절성(seasonality) 라고 한다.
계절성 그래프 : Seasonal Plot
계절성 그래프(seasonal plot)는 관측된 데이터를 개별 계절(season)별로 중첩해서 그려주는 것이 autoplot와 다른 점이다. tsibble 데이터의 계절성 그래프를 그릴 때는 gg_season() 함수를 사용한다. 아래는 동일한 데이터를 사용하여 계절성 관점에서 그린 계절성 그래프이다.
A10 %>% gg_season(Cost, labels = "right") + # 계절성 그래프 labs(y = "호주$ (백만불)", title = " 계절성 그래프(Antidiabetic drug 판매 현황)" )
계절성 그래프를 살펴보면, Time Plot에서 확인했던 계절적 추세에 보다 더 상세하게 계절적 변화의 패턴을 파악할 수 있다. 즉 비용은 매년 증가하는 추세이며, 2월에는 최저점을 형성했다가 점차적으로 증가하여 연말에 최고에 이르게 되는 것을 알 수 있다. (이는 아마도 질병 발생 패턴이라기 보다는 호주의 의료비 정산과 관련있는 제도 때문일것으로 추측된다.) 이런 계절성 그래프는 아래와 같이 Polar 형태로 표현할 수도 있다.
A10 %>% gg_season(Cost, labels = "right", polar = TRUE) + # Polar(방사) 형 labs(y = "호주$ (백만불)", title = " 계절성 그래프(Antidiabetic drug 판매 현황)" )
MUltiple Seasonal Plot
데이터에 둘 이상의 계절적 패턴이 복합적으로 존재하는 경우, gg_season() 함수의 period 인자를 사용하여 필요한 계절적 그래프를 선택해서 그릴 수 있다. vic_elec 데이터는 호주 빅토리아 주의 전력 수요를 30분 간격으로 측정한 데이터이다. period 인자를 지정하여 일간 패턴, 주간 패턴 또는 연간 패턴을 그래프로 그릴 수 있다.
vic_elec %>% gg_season(Demand, period = "day") + # 주기를 일일로 --> 일간 전력수요변화 theme(legend.position = "none") + labs(y="MWh", title="일간 전력수요 패턴 ")
vic_elec %>% gg_season(Demand, period ="week") + # 주기를 주간으로 --> 주간단위 전력수요변화 theme(legend.position = "none") + labs(y="MWh", title="주간 전력수요 패턴 ")
vic_elec %>% gg_season(Demand, period ="year") + # 주기를 연간으로 --> 년간단위 전력수요변화 theme(legend.position = "none") + labs(y="MWh", title="년간 전력수요 패턴 ")
계절성 분할 그래프(Seasonal Subseries Plot)
계절성 분할 그래프는 계절성 데이터를 세부적인 기간으로 분할하여 그래프를 각각 제시한다. 다음 예를 들어 호주의 여행 관련 데이터인 tourism 데이터를 이용하여 계절성 그래프(Seasonal Plot)와 Seasonal Subseries Plot의 차이를 살펴보자.
tourism %>% filter(Region == "Melbourne" & State == "Victoria") %>% gg_season(Trips) + # Seasonal PLot labs(title = "호주 빅토리아주 여행객 Seasonal Plot")
tourism %>% filter(Region == "Melbourne" & State == "Victoria" ) %>% gg_subseries(Trips) + labs(title = "호주 빅토리아주 여행객 Seasonal Subseries Plot")
시계열 데이터의 분해(Decomposition)
시계열 데이터 분해는 시계열 데이터를 구성하는 여러 구성 요소로 분해하여 각 구성 요소의 특성을 파악하는 기법이다. 시계열 데이터 분해는 두 가지 주요 분해 방법이 있다. 가법 모델(Additive Model)과 승법 모델(Multiplicative Model) 이 그것이다.
가법 모델(Additive Model)
가법 모델은 시계열 데이터가 추세(Trend), 계절성(Seasonality), 그리고 잔차(Residual)의 세 가지 성분의 합으로 표현될 수 있다고 가정한다. 가법 모델은 데이터의 변동이 시간에 따라 일정한 경우에 적합하다.
\[Y_t = T_t + S_t + R_t\]
\(Y_t\)는 시점 t에서의 관측값 \(T_t\)는 시점 t에서의 추세 성분 \(S_t\)는 시점 t에서의 계절 성분 \(R_t\)는 시점 t에서의 잔차 성분승법 모델(Multiplicative Model)
승법 모델은 시계열 데이터가 추세, 계절성, 그리고 잔차의 곱으로 구성된다고 가정한다. 승법 모델은 데이터의 변동성이 시간에 따라 변할 때 사용된다.
\[Y_t = T_t \times S_t \times R_t\]성분분해 사례
위에서 사용한 A10 데이터의 성분을 분해해보자.
A10 %>% model(stl = STL(Cost)) %>% # 분해해서 dable(decomposion table 생성 ) components() # 성분별로 보자
# A dable: 204 x 7 [1M] # Key: .model [1] # : Cost = trend + season_year + remainder .model Month Cost trend season_year remainder season_adjust <chr> <mth> <dbl> <dbl> <dbl> <dbl> <dbl> 1 stl 1991 7 3.53 3.27 -0.127 0.383 3.65 2 stl 1991 8 3.18 3.31 -0.116 -0.0129 3.30 3 stl 1991 9 3.25 3.35 -0.0872 -0.0104 3.34 4 stl 1991 10 3.61 3.39 0.134 0.0872 3.48 5 stl 1991 11 3.57 3.43 0.254 -0.118 3.31 6 stl 1991 12 4.31 3.47 1.64 -0.804 2.67 7 stl 1992 1 5.09 3.51 1.81 -0.233 3.28 8 stl 1992 2 2.81 3.55 -1.14 0.408 3.96 9 stl 1992 3 2.99 3.59 -0.704 0.0999 3.69 10 stl 1992 4 3.20 3.63 -0.727 0.302 3.93 # ℹ 194 more rows
tsibble 객체의 구성을 분해할 때 사용한 함수는 STL 함수이다. A10 데이터를 가법 분해하여 각각의 성분들을 제시하였다. “dable”은 decomposed table의 약자로 시계열 데이터의 분해된 테이블을 의미한다. Cost는 trend, season_year, 및 remainder의 합임을 알 수 있다. season_adjust는 Cost에서 계절 성분(season_year)의 영향을 배제(제외)한 값이다. 이것을 autoplot으로 가시화 시키면 다음과 같은 성분별 그래프를 얻을 수 있다.
A10 %>% model(stl = STL(Cost)) %>% components() %>% autoplot() + labs(title = " 시계열 데이터의 성분 분해 ")
데이터의 성분을 분해한 그래프가 각각 제시되었다. 여기서 왼쪽 음영 처리된 바의 의미는 각 성분 그래프의 스케일이 다르기 때문에 참고로 붙여준 상대적인 스케일을 의미한다. 즉 데이터의 동일한 양을 설명하려면, 바의 크기만큼이 필요하다는 의미로 해석하면 된다.
시계열 데이터 안에 여러 개의 계절 성분이 포함된 경우를 분해하면 여러 계절 성분이 포착되어 그래프에 도시된다. 위에서 사용된 호주 빅토리아주 전력소요 데이터가 그 예이다.
vic_elec %>% model(stl = STL(Demand)) %>% components() %>% autoplot() + labs(title = "호주 빅토리아주 전력소요 데이터 분해결과")
그래프를 살펴보면 trend(추세성분)와 remainder(나머지) 외에 season_year(연간계절성분), season_week(주간계절성분), season_day(일간계절성분)와 season_hour(시간계절성분)이란 네 가지 계절성분이 존재하고 있음을 알 수 있다.
시차그래프(Lag Plot)와 자기상관(Autocorrelation)
시계열 데이터는 index를 기준으로 t 시점의 관측치 \(y_t\)와 \(k\) 만큼 시차를 갖는 \(y_{t-k}\)의 관측치의 관계를 파악하는 것이 중요하다. 먼저 두 시점 간의 데이터를 산점도로 작성하는 시차 그래프(Lag plot)를 알아본다.
시차 그래프(Lag Plot)
관측치 \(y_t\)와 \(k\) 만큼 lag된 \(y_{t-k}\) 값을 산점도로 그린 것이 시차그래프다. 일반적인 데이터 분석 시에 산점도를 통해서 두변수간이 상관관계를 확이 할 수 있듯이, \(y_t\)와 \(y_{t-k}\)의 Lag Plot을 통해 두 시점 간의 차이에 대한 상관관계를 확인할 수 있다. 호주의 공산품 생산품 데이터 중 맥주생산에 대한 Lag plot을 작성해 보자.
aus_production %>% filter(year(Quarter) >= 2000) %>% # index가 Quarter인데 연도로 필터링 gg_lag(Beer, geom = "point") + labs(x = "lag(Beer, k)", title = "호주 맥주 생산량 Lag plot")
모든 그래프의 y축에는 \(y_t\)값, x축에는 \(y_{t-k}\)의 값을 배치하여 산점도를 그린 그래프이다. 이를 통해서 시차에 따른 데이터 관계를 파악할 수 있다. 에를 들어 lag1 그래프는 \(y_t\)와 1시차 떨어진 \(y_{t-1}\)의 산점도 그래프이다. 점들의 색깔이 다른 이유는 분기별로 구분해서 도시했기 때문이다. lag4와 lag8 그래프는 두 값 간에 양의 상관관계가 높다는 것을 알 수 있고, lag2와 lag6 그래프는 음의 상관관계가 강하게 나타난다는 것을 알 수있다. 이는 후에 소개되는 ACF 도표를 통해서도 확인이 가능하다.
자기 상관(Autocorrelation)
자기상관(autocorrelation)은 시계열의 시차 값(lagged values) 사이의 선형 관계를 측정한다. 예를 들어 상관관계 \(r_1\)은 \(y_t\)와 \(y_{t-1}\)간의 상관관계를 계산한 값이고 \(r_2\)는 \(y_t\)와 \(y_t-2\)의 상관관계 값이다. 자기 상관을 일반화한 \(r_k\)는 다음과 같이 표현할 수 있다.
\[ r_k = \frac{\sum_{t=k+1}^{T} (y_t - \bar{y})(y_{t-k} - \bar{y})}{\sum_{t=1}^{T} (y_t - \bar{y})^2} \]위 호주의 맥주생산 자기상관계수는 아래와 같이 계산한다. ACF는 Auto Correlation Function의 약자이다.
aus_production %>% filter(year(Quarter) >= 2000) %>% ACF(Beer, lag_max = 9)
# A tsibble: 9 x 2 [1Q] lag acf <cf_lag> <dbl> 1 1Q -0.0530 2 2Q -0.758 3 3Q -0.0262 4 4Q 0.802 5 5Q -0.0775 6 6Q -0.657 7 7Q 0.00119 8 8Q 0.707 9 9Q -0.0888
ACF는 자기상관도표로 가시화 할수 있다.
aus_production %>% filter(year(Quarter) >= 2000) %>% ACF(Beer, lag_max = 9) %>% autoplot() + labs(title = " 자기상관 도표 ")
ACF 도표에서 y축은 상관계수를 x 축은 시차를 나타낸다. 가로로 그려진 점선은 95% 신뢰구간에서 상관관계를 판단하는 기준선이다. ACF 도표를 보면, lag4, lag8에서는 강한 양의 상관관계가 식별되고, lag2와 lag6에서는 강한 음의 상관관계가 나타남을 알 수 있다. 이것은 위에서 살펴본 Lag plot와 동일한 함의를 보인다.
한가지 다른 예로 위에서 살펴본 호주의 처방전 데이터인 PBS 데이터중 “A10”(Antidiabetic drug)의 의료비용 데이터에 대한 Time Plotd와 ACF 도표를 살펴보자.A10 %>% autoplot() + labs(title = "호주 Antidiabetic drug 데이터의 Time Plot ") -> a10_time A10 %>% ACF(TotalC, lag_max = 50) %>% autoplot() + labs(title = "호주 Antidiabetic drug 데이터의 ACF ") -> a10_acf grid.arrange(a10_time, a10_acf, ncol=2)
왼쪽의 Time Plot을 보면 데이터에 추세성분과 계절성분이 동시에 존재함을 알 수 있다.
데이터에 추세가 존재할 때, 작은 크기의 시차에 대한 자기상관은 큰 양의 값을 갖는 경향이 있다. 왜냐하면 시간상으로 가까운 관측치들이 관측값의 크기도 비슷하기 때문이다. 그래서 추세가 있는 시계열의 ACF는 양의 값을 갖는 경향을 보이며, 시차가 증가함에 따라 서서히 감소하게된다.
데이터에 계절성이 존재할 경우의 자기상관은 다른 시차의 경우보다 계절성 시차의 주기와 연계되어 크게 나타나게 된다. 오른쪽 ACF 도표를 보면 상관관계가 시차에 따라 서서히 줄어들며, 일정한 주기로 상관관계가 높아 짐을 알 수 있어, 데이터에 추세와 계절성이 존재함한다고 판단할 수 있다.'데이터' 카테고리의 다른 글
기상분석 II(가시거리 분석) (1) 2024.10.27 기상분석 I (바람 분석) (7) 2024.10.13 시계열 분석 시리즈 I (Tsibble 객체 다루기) (0) 2024.03.03 데이터 주무르기 (1) 2024.02.18 Association Rule 분석(장바구니 분석) (2) 2024.02.04