*본 내용은 시계열데이터 강의 내용 중 일부분을 요약한 내용입니다
모델 성능 평가 후 개선 할 점이 있는지, 모델이 신뢰성이 있는 것인지를 파악하기 위해서 잔차진단을 합니다.
총 네가지 스텝으로 구성되어있습니다.
1. 정상성 테스트
정상성이란 시간의 흐름에 따라 통계적 특성이 변하지 않는다. 즉, 시계열이 정상성이다.
통계적 특성: 주로 평균(Mean)과 분산(Variance)/공분산(Covariance)를 얘기하지만 이를 포함한 모든 분포적 특성을 총칭합니다.
2. 정규분포 테스트(normality Test)
3. 자기상관 테스트(Autocorrelation Test)
4. 등분산성 테스트(Homoscedasticity)
잔차진단 결과 백색잡음이면 패턴을 잘 추출 했다는 의미 입니다.
즉, 찾아낼 패턴을 다 찾은 의미인데, 그렇지 못한 경우에는 시각화 그래프가 어떠한 추세를 보인다던가 정규분포을 따르지 않는다 던가, 분산이 일정치 않고 뒤죽박죽 튄다 던가 하는 등 판별기준이 있습니다. 실습코드는 아래에 있습니다
백색잡음
백색잡음(White Noise)는 2가지의 속성을 만족해야 하며 하나라도 만족하지 못하면 모델이 개선의 여지가 있음을 의미합니다. 무작위한 진동 패턴(fx가 y에 최대한 근접할때 생긴다)
1. 잔차들은 정규분포이고, 평균 0과 일정한 분산을 가진다.
정규분포인지 아닌지를 알수 있는 방법은 시각화와 검정통계량 2가지가 있다.
*시각화: 잔차들의 값을 빈도체크하여 시각화를 할때 정규분포 모양을 따르는지 확인할수 있다.
*검정통계량 Shapiro-Wilk Test 외에 여러 방법이 존재, 유의확률을 통해 의사결정을 하여 정규분포인지를 판별(4.6.2 교육자료)
2. 잔차들이 시간의 흐름에 따라 상관성이 없어야 한다.
아무 잔차 2개의 시점을 뽑았을때, 이 둘의 corr은 0이여야 한다. corr=0은 서로 관련성이 없으므로 독립이라는 뜻이다.
자기상관함수(Autocorrelation Fundtion)
한 변수 내에 다른 시간 축에 대한 데이터 상관성 분석합니다. 시간 흐름에 따라 상관성이 존재하는지를 알아 볼때 사용됩니다.
특정 변수를 lag값을 취한 뒤 corr이 있는지 계산하며 아래 그래프의 파란색 실선 범위 안에 있으면 자기상관은 없다고 판별합니다. 파란색 실선은 유의수준과 같은 역할을 합니다
정리 차원에서 회귀분석 가정들 살펴보기(모두 만족시 패턴을 잘 뽑아낸 경우이다)
- 종속변수와 독립변수 간에 선형서의 관계를 가져야 한다
- 독립변수들 간에 서로 독립이어야 한다
- 잔차의 분포가 정규분포이어야 한다
- 잔차들이 서로 독립적으로 움직여야 한다
- 잔차들의 분산이 서로 같아야 한다
#잔차와 실제 잔차 인덱스=> 시간으로 확인하든 인덱스로 확인하든 순서는 보존가능해진다=> 공부 필요
Resid_tr_reg1['Rownum'] = Resid_tr_reg1.reset_index().index
#시각화 작업
# Stationarity(Trend) Analysis: 정상성 시각화
sns.set(palette='muted', color_codes=True, font_scale=2)
sns.implot(x='RowNum', y='Error', data=Resid_tr_reg1.iloc[1:], fit_reg='True', size=5.2,
aspect=2, ci=99, sharey='True')
# Normal Distribution Analysis_정규분포 시각화
figure, axes = plt.subplots(figsize=(12,8))
sns.displot(Resid_tr_reg1['Error'], norm_hist='True', fit=stats.norm)
## Lag Analysis
'''
x축: 잔차의 오리지널 값
y축: 1시점 이동된 시점
이 두개 시점의 correlation 값들을 표현
선형성 모양의 상관성이 있어 보인다.
2.4.2의 백색잡음이 되기 위한 조건은 어떠한 시점 두개를 뽑아도 corr이 0이여야 한다
하지만 아래 그래프를 통해, corr이 시점에 따라 변화 하고 있으므로 백색잡음이 아니다.
'''
figure, axes = plt.subplots(1,4, figsize=(12,3))
pd.plotting.lag_plot(Resid_tr_reg1['Error'], lag=1, ax=axes[0])
pd.plotting.lag_plot(Resid_tr_reg1['Error'], lag=5, ax=axes[1])
pd.plotting.lag_plot(Resid_tr_reg1['Error'], lag=10, ax=axes[2])
pd.plotting.lag_plot(Resid_tr_reg1['Error'], lag=50, ax=axes[3])
# Autocorrelation Analysis_자기상관 시각화
figure , axes = plt.subplots(2,1, figsize=(12,5))
'''
lags=100: 100 lag를 그려서 수치를 알려준다
y축: corr
0번째가 1인 이유: et와 자기자신 et의 상관성 이기 때문에 1이다.
밑면에 회색그림자:유의수준 범주, 이 값을 벗어난 만큼 자기상관이 있다고 판별하고
이 범주 안에 있다면 자기상관은 0이다.(없다고 판별)
'''
figure = sm.graphics.tsa.plot_acf(Resid_reg1['Error'], lag =100, use_vlines=True, ax=axes[0])
figure = sm.graphics.tsa.plot_pacf(Resid_reg1['Error'], lags=100, ues__vlines=True, ax=axes[1])
#검정통계량 작업
# Error Analysis(Statistics)
# Checking Stationarity
# Null Hypothesis(대중 주장): The Time-series is non-stationalry
#adfuller: ADF 정상성테스트
stationarity = pd.Series(sm.tsa.stattools.adfuller(Resid_reg1['Error'])[0:4],
index=['Test Statistics', 'p-value', 'Used Lag', 'Used Observations'])
for key , value in sm.tsa.stattools.adfuller(Resid_tr_reg1['Error'])[4].items(): #각 p_value마다의 통계량
Stationarity['Critial Value(%s)'%key]=value
Stationarity['Maximum Information Criteria'] = sm.tsa.stattools.adfuller(Resid_tr_reg1['Error'])[5]
Stationarity = pd.DataFrame(Stationarity, columns=['Stationarity'])
# Checking of Normality(정규분포 테스트)
# Null Hypothesis(대중 주장): The residuals are normally distributed
Normality= pd.DataFrame([stats.shapiro(Resid_tr_reg1['Error'])], index=['Normality'], columns=['Test Statistics','p-value']).T
# Checking for Autocorrelation
# Null Hypothesis: Autocorrelation is absent = 자기상관은 없다
Autocorrelation = pd.concat([pd.DataFrame(sm.stats.diagnostic.acorr_ljungbox(Resid_tr_reg1['Error'], lags=[1,5,10,50])[0], columns=['Test Statistics']),
pd.DataFrame(sm.stats.diagnostic.acorr_ljungbox(Resid_tr_reg1['Error'], lags=[1,5,10,50])[1], columns=['p-value'])], axis=1).T
Autocorrelation.columns = ['Autocorr(lag1)', 'Autocorr(lag5)', 'Autocorr(lag10)', 'Autocorr(lag50)']
Autocorrelation.columns = ['Autocorr(lag1)', 'Autocorr(lag5)', 'Autocorr(lag10)', 'Autocorr(lag50)']
# Checking Heteroscedasticity(등분산성)
# Null Hypothesis: Error terms are homoscedastic(등분산이다)
# 입력form이 array로 넣어야 하므로 X_train.values
#two-sided: 크냐,작냐,같냐 구분하는 방식
# Alternative: 가설의 방향
Heteroscedasticity = pd.DataFrame([sm.stats.diagnostic.het_goldfeldquandt(Resid_tr_reg1['Error'], X_train.values, alternative='two-sided')],
index=['Heteroscedasticity'], columns=['Test Statistics', 'p-value', 'Alternative']).T
Error_Analysis = pd.concat([Stationarity, Normality, Autocorrelation, Heteroscedasticity], join='outer', axis=1)
#row 순서 정렬
Error_Analysis = Error_Analysis.loc[['Test Statistics', 'p-value', 'Alternative', 'Used Lag', 'Used Observations',
'Critical Value(1%)', 'Critical Value(5%)', 'Critical Value(10%)',
'Maximum Information Criteria'],:]
'Data Diary' 카테고리의 다른 글
2021-03-19(시계열데이터 심화6_다중공선성 제거&정상성) (0) | 2021.03.19 |
---|---|
2021-03-18(시계열데이터 심화5_현실성을 반영한 데이터패턴& Scaling) (0) | 2021.03.18 |
2021-03-16(시계열데이터 심화3_시각화&모델적용&검증지표) (0) | 2021.03.16 |
2021-03-15(시계열데이터 심화2_FE&Data split) (0) | 2021.03.15 |
2021-03-13(Opencv 복습) (0) | 2021.03.13 |