성분별로 model을 만들어 정확한 분석을 하고자 함.
즉 하나의 model이기는 하나 세분화 한다고 생각.
시계열의 성분
불규칙 성분
예측 불가한 성분
체계적 성분
분해법의 기본모형
근데 이건 추세성분과 잔차성분이 완전하게 독립적인 경우이고 실제는 불가능 하니 한번에 model architecture를 구성하여 적합한다.
data food; infile 'D:\UOS_2021_2\time_analysis\SAS_codes\data\food.txt'; input food @@; date = intnx('month','1jan80'd,_n_-1); format date monyy; t+1; /* 행 베이스 계산이므로 */ mon = month(date); if mon=1 then i1=1; else i1=0; if mon=2 then i2=1; else i2=0; if mon=3 then i3=1; else i3=0; if mon=4 then i4=1; else i4=0; if mon=5 then i5=1; else i5=0; if mon=6 then i6=1; else i6=0; if mon=7 then i7=1; else i7=0; if mon=8 then i8=1; else i8=0; if mon=9 then i9=1; else i9=0; if mon=10 then i10=1; else i10=0; if mon=11 then i11=1; else i11=0; if mon=12 then i12=1; else i12=0; run;
reading data
proc reg data=food ; model food= t/dw; output out=trendata p=trend ; id date; run;
추세모형 적합
이때 예측값을 따로 저장해 준다.data adtrdata; set trendata; adjtrend=food/trend; run;
승법 모형이므로 원자료에서 추세모형으로 추정된 예측값들을 나눠준다.
즉 이는 추세성이 분리된 자료이고 따라서 계절모형을 적합한다.proc reg data = adtrdata; model adjtrend = i1 - i12 / dwprob; run;
자기 상관성이 보인다.
따라서 자기회귀오차모형으로 다시 적합한다.proc autoreg data=adtrdata; model adjtrend=i1-i12/noint nlag=13 dwprob backstep; output out=seasdata p=seasonal; run;
정리해보자면 다음과 같다.
0. 승법모형을 적용할꺼다.
1. 원자료에 대하여 추세모형을 적합한다.
2. 원자료에 추세모형으로 적합한 예측값을 나누어 추세성을 분리한다.
3. 나눈 자료를 계절모형으로 적합한다. 단, 이때 자기상관성이 보이므로 자기회귀오차모형으로 적합한다.
data all; set seasdata; keep date food trend seasonal irregular fitted; irregular=adjtrend/seasonal; fitted=trend*seasonal; run; proc print data=all; var date food trend seasonal irregular fitted; run;
이는 원자료를 추세성과 계절성으로 분리하여 예측한 자료이다.
이때 두 모형으로 예측값으로 나눈 불규칙 성분을 분리한다. -> 진짜 불규칙인지 검토하기 위해
이는 모형의 잔차와는 다르다! 주의하자.
( 모형의 잔차는 예측값과 실제값의 차이이다. )
예측값은 추세모형과 계절모형의 예측값들의 곱이다.
proc arima data=all; identify var= irregular nlag=12; run;
위에서 분리한 불규칙성분 의 자기상관성이 있는지 검토한다.
/** [그림 4-1] **/ proc sgplot data=all; series x=date y=food/ lineattrs=(pattern=1 color=blue); series x=date y=trend/ lineattrs=(pattern=2 color=black); run; /** [그림 4-2] **/ proc sgplot data=all; series x=date y=seasonal; run; /** [그림 4-3] **/ proc sgplot data=all; series x=date y=irregular; refline 1.0/ axis=y; run; /** [그림 4-4] **/ proc sgplot data=all; series x=date y=food/ lineattrs=(pattern=1 color=blue); series x=date y=fitted/ lineattrs=(pattern=2 color=black); run;
이동평균법
이거 예측모델이 아니고 전처리라고 생각하는게 맞을듯.
심지어 centered이면 예측이 불가함.
data index; infile 'D:\UOS_2021_2\time_analysis\SAS_codes\data\mindex.txt'; input index @@; date=intnx('month','1jan86'd,_n_-1); format date monyy.; t+1; run;
데이터를 읽는다.
/** expand 절차를 이용하여 이동평균값 구하기 **/ proc expand data=index out=index1; convert index = m3_centered / transformout = ( cmovave 3 ); convert index = m7_centered / transformout = ( cmovave 7 trim 3 ); convert index = m3 / transformout = ( movave 3 ); convert index = m7 / transformout = ( movave 7 ); run;
index라는 dataset의 index라는 변수명을 m3_centered로 /뒤의 조건에 따라 convert하라는 의미.
cmovave
는 양쪽 데이터를 기준으로 중심 데이터를 이동평균.
movave
는 앞 데이터를 기준으로 다음 데이터를 이동평균.
trim
은 해당 숫자만큼 양쪽에서 데이터 삭제./** <표 4-4> **/ proc print data=index1; var index m3 m7; run;
이동평균값 확인
/** [그림 4-5] **/ proc sgplot data=index1; series x=date y=index/ lineattrs=(pattern=1 color=black); series x=date y=m3_centered/ lineattrs=(pattern=2 color=blue); xaxis values=('1jan86'd to '1jan94'd by year); run; /** [그림 4-6] **/ proc sgplot data=index1; series x=date y=index/ lineattrs=(pattern=1 color=black); series x=date y=m7_centered/ lineattrs=(pattern=2 color=blue); xaxis values=('1jan86'd to '1jan94'd by year); run;
실제 데이터와 단순이동평균된 데이터 비교(확인)
이렇게 생각하자.
일단 이동평균법은 절대로 model이 아니다. 그냥 단순 전처리이다.( 이게 틀린 말인데 이렇게 이해하는게 좋다. )
근데 그래서 이걸 왜 하는데?
그럼 이제 이동평균법을 이용해서 계절성을 분리할 수 있다.
4.1에서는 임의로 추세성과 계절성을 분리하여 각각 modeling 하였다.
이제 여기서는 이동평균법의 몇개의 데이터를 평균으로 할것이가에 대한 hyper parameter인 m을 계절성의 주기인 s와 같게 하자.
그러면 계절성의 주기만큼 평균을 계산하게 된다.
즉, 계절성이 사라지는 것이다.
극단적으로 예를들어보면 계절성의 주기성이 12이고 각 데이터는 매달 측정된 관찰값이라고 하자.
그리고 이동평균법의 m을 12로 한다면 적용된 데이터는 12달 의 평균값이다. 항상 1월부터 시작하는 것은 아니나 원래 주기인 12를 계속 평균을 내므로 이는 주기성이 사라진다고 보면 된다.
이렇게 하여 계절의 주기성을 제거하고 추세(+순환)성분을 얻는다. 이후 추세 분석을 하는것이 아니라 그냥 이게 추세성분이 되는거다.
다음 원자료(이동평균적용 전이다. 헷갈리지 말자)에서 적합된 추세성분을 빼주면 이동평균에 의해 제거된 계절성이 남으므로 이는 곧 계절성분(+불규칙성분) 이다.
즉, 이것이 그냥 계절성분이다. (이를 가지고 계절성분 분석을 하는것이 아니다.)
이후 몇가지의 step이 더 남아있다.
문제발생
proc expand data=food out=foodtest;
convert food = test / transformout = ( cmovave 12 );
convert food = tc / transformout = (cd_tc 12);
run;
이거 둘의 결과 다름 -> 질문함.
해보자.
예시는 가법모형이다.
data food; infile 'D:\UOS_2021_2\time_analysis\SAS_codes\data\food.txt'; input food @@; date=intnx('month','1jan80'd,_n_-1); format date monyy.; t+1; mon=month(date); run;
데이터를 얻는다.
/** expand 절차를 이용하여 가법모형의 구성 성분들을 추정하기 **/ proc expand data=food out=food2; convert food=tc/transformout=(cd_tc 12); /*이거 이상한데? 그냥 오타인거 같은데...*/ convert food=s/transformout=(cda_s 12); convert food=i/transformout=(cda_i 12); convert food=sa/transformout=(cda_sa 12); run;
이동평균법으로 계절성분을 제거하여 추세+순환성분을 얻는다.
원자료에서 이를 뺀 계절성분을 얻는다.
불규칙성분을 얻는다.
계절조정한 성분을 얻는다.
계절조정이란 원자료에서 계절성분을 추정하여 제거하는 절차.
즉, 앞의 이동평균법 또한 계절조정이라고 볼 수 있다.
/** X12 절차에서 X11 방법에 의해 여러 가지 성분들을 산출하기 **/ proc X12 data=food seasons=12 start=jan1980; var food; x11; output out=foodout a1 d10 d11 d12 d13; run;
D10 - D13 순서대로 계절성분, 계절조정계열, 추세+순환성분, 불규칙성분
/** <표 4-7> **/ proc print data=foodout; run;
/** [그림 4-11]~[그림 4-14] 그리기 **/ data foodout; set foodout(rename=(_date_=date food_a1=food food_d10=d10 food_d11=d11 food_d12=d12 food_d13=d13 )); label food=" " d10=" " d11=" " d12=" " d13=" " ; run;
/** [그림 4-11] **/ title "Final seasonal factors"; proc sgplot data=foodout; series x=date y=d10; run;
/** [그림 4-12] **/ title "Original time series vs Seasonally adjusted series"; proc sgplot data=foodout; series x=date y=food/ lineattrs=(pattern=1 color=blue); series x=date y=d11/ lineattrs=(pattern=2 color=black); run;
/** [그림 4-13] **/ title "Original time series vs Trend cycle"; proc sgplot data=foodout; series x=date y=food/ lineattrs=(pattern=1 color=blue); series x=date y=d12/ lineattrs=(pattern=2 color=black); run;
/** [그림 4-14] **/ title "Irregular component"; proc sgplot data=foodout; series x=date y=d13; refline 1.0/ axis=y; run;
/* 불규칙 성분이 진짜 불규칙인지 자기상관계수 구해보기 */ proc arima data=foodout; identify var=d13 nlag=24; run;