스튜던트 잔차(rstudent)
관련된 내용
오차를 계산하기 위해 식 1과 같이 hat 행렬을 사용할 수 있습니다.
\begin{align} \hat{y} &= Xb\\&=X(X^TX)^{-1}X^Ty \\&=Hy\\ e &= y-\hat{y}\\& = y-Hy\\ &=(1-H)y\end{align} | (식 1) |
식 1로부터 오차의 분산은 반응변수 y의 분산에 (1-H)를 곱한것과 같습니다(확률과 주요통계량: 분산의 식3 참조). 설명변수의 영향을 나타내는 것이므로 H 대신 hat 행렬의 대각요소를 고려하면 식 1은 식 2와 같이 나타낼 수 있습니다. 또한 추정치들의 모분산(σ2) 대신에 표본분산(s2)을 사용합니다.
σe2 = (1 − hii)s2 | (식 2) |
식 2에서 계산된 각 샘플 오차의 분산을 사용하여 표준화할 수 있습니다. 오차는 평균이 0인 정규분포를 가정하므로 그 결과는 식 3과 같이 스튜던트 잔차(studentized residuals)가 됩니다.
\begin{align}\text{rstudent}&=\frac{\text{error}_i}{\sigma\sqrt{1-h_{ii}}}\\&\approx \frac{\text{error}_i}{s\sqrt{1-h_{ii}}} \end{align} | (식 3) |
생성한 모형에서 추정치들의 이상치 여부는 추정치와 관측치의 차이인 잔차(residuals)를 기반으로 판단할 수 있습니다. 즉, 이상치의 결정기준으로 잔차를 사용하기 위해 전체의 스케일을 표준화 또는 정규화시킨 값에 설명변수의 레버리지를 고려한 스튜던트 잔차(studentizedres residuals)를 사용합니다
잔차의 경우 데이터의 단위에 따라 스케일이 달라지는 반면 스튜던트 잔차의 경우 스케일 자체가 표준화 되었기 때문에 데이터의 스케일이 달라져도 직접적인 비교가 가능해집니다. 일반적으로 그 절대값이 3이상인 경우 이상치로 간주됩니다.
import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt import FinanceDataReader as fdr import statsmodels.api as sm from scipy import stats
st=pd.Timestamp(2021,1, 1) et=pd.Timestamp(2024, 5, 10) kos=fdr.DataReader('KS11',st, et)[["Open","Close"]] kos.index=range(len(kos)) X=kos.values[:,0].reshape(-1,1) y=kos.values[:,1].reshape(-1,1) #독립변수 정규화(표준화) xScaler=StandardScaler().fit(X) X_n=xScaler.transform(X) #반응변수 정규화(표준화) yScaler=StandardScaler().fit(y) y_n=yScaler.transform(y) X_n0=sm.add_constant(X_n) X_n0.shape, y_n.shape reg=sm.OLS(y_n, X_n0).fit()
스튜던트 잔차는 get_influence()
의 결과의 "student_resid"열 자료로 확인할 수 있습니다. 그림 1에서 잔차와 스튜던트 잔차를 나타내었습니다.
influence=reg.get_influence() infSummary=influence.summary_frame() res_std=infSummary["student_resid"] res_std[:3]
0 3.175307 1 2.168863 2 -0.968262 Name: student_resid, dtype: float64
plt.figure(figsize=(6, 3)) plt.subplots_adjust(hspace=0.6) plt.subplot(2,1,1) plt.stem(reg.resid) plt.title("a) Residual") plt.subplot(2,1,2) plt.stem(res_std) plt.axhline(3, c='g', ls='--') plt.axhline(-3, c='g', ls='--') plt.title("b) Studenized Residual") plt.show()
스튜던트 잔차를 적용하여 이상치를 제거한 후의 회귀모형으로부터의 오차는 정규성에 근접하는 것으로 개선됩니다. 이 결과는 그림 2(b)로 시각화 할 수 있습니다. 이상치를 고려하지 않은 회귀모델에서의 오차의 Q-Q plot을 나타내는 그림 2(a)와 비교하면 상당한 개선이 있음을 알 수 있습니다.
out_stres=np.where(np.abs(res_std)>3)[0] print(out_stres)
[ 0 4 11 19 20 35 36 37 187 225 227 265 360 699]
ind_stres=np.delete(X_n0, out_stres, axis=0) de_stres=np.delete(y_n, out_stres, axis=0) reg_stres=sm.OLS(de_stres, ind_stres).fit() print(f"회귀계수: {np.around(reg_stres.params, 3)}\nR2: {reg_stres.rsquared.round(3)}")
회귀계수: [-0. 0.997] R2: 0.995
stat, pVal=stats.shapiro(reg_stres.resid) np.around(pd.DataFrame([stat,pVal], index=["통계량", "p-value"]), 3)
0 | |
통계량 | 0.997 |
p-value | 0.123 |
plt.figure(figsize=(7,3)) plt.subplots_adjust(wspace=0.4) plt.subplot(1,2,1) errorRe=stats.probplot(reg.resid, plot=plt) plt.title("(a)Q-Q plot") plt.subplot(1,2,2) fig=stats.probplot(reg_stres.resid, plot=plt) plt.title("(b)Q-Q plot") plt.show()
일반적으로 이상치와 레버리지 값에 의한 영향은 선형회귀모형을 구축하는 기본 이론인 최소자승법으로 해결하기는 어렵고 이상치에 둔감한 로버스트(robust) 방법이나 변수의 조정 등으로 그 영향을 감소시킬 수 있습니다.
댓글
댓글 쓰기