기본 콘텐츠로 건너뛰기

[ML] 결정트리(Decision Tree) 모델

[data analysis] 스튜던트 잔차(rstudent)

스튜던트 잔차(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
그림 1. 잔차스튜던트잔차.
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
그림 2. (a) 원시자료에 대한 회귀모델의 잔차 qqplot, (b) rstudent에 의한 이상치를 제거한 자료에 대한 회귀 모델의 잔차의 qq plot.
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) 방법이나 변수의 조정 등으로 그 영향을 감소시킬 수 있습니다.

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. $$\tag{1} A = PBP^{-1} \Leftrightarrow P^{-1}AP = B $$ 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. \begin{align}\tag{식 2} B - \lambda I &= P^{-1}AP – \lambda P^{-1}P\\ &= P^{-1}(AP – \lambda P)\\ &= P^{-1}(A - \lambda I)P \end{align} 식 2의 행렬식은 식 3과 같이 정리됩니다. \begin{align} &\begin{aligned}\textsf{det}(B - \lambda I ) & = \textsf{det}(P^{-1}(AP – \lambda P))\\ &= \textsf{det}(P^{-1}) \textsf{det}((A – \lambda I)) \textsf{det}(P)\\ &= \textsf{det}(P^{-1}) \textsf{det}(P) \textsf{det}((A – \lambda I))\\ &= \textsf{det}(A – \lambda I)\end{aligned}\\ &\begin{aligned}\because \; \textsf{det}(P^{-1}) \textsf{det}(P) &= \textsf{det}(P^{-1}P)\\ &= \textsf{det}(I)\end{aligned}\end{align} 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같

[matplotlib] 히스토그램(Histogram)

히스토그램(Histogram) 히스토그램은 확률분포의 그래픽적인 표현이며 막대그래프의 종류입니다. 이 그래프가 확률분포와 관계가 있으므로 통계적 요소를 나타내기 위해 많이 사용됩니다. plt.hist(X, bins=10)함수를 사용합니다. x=np.random.randn(1000) plt.hist(x, 10) plt.show() 위 그래프의 y축은 각 구간에 해당하는 갯수이다. 빈도수 대신 확률밀도를 나타내기 위해서는 위 함수의 매개변수 normed=True로 조정하여 나타낼 수 있다. 또한 매개변수 bins의 인수를 숫자로 전달할 수 있지만 리스트 객체로 지정할 수 있다. 막대그래프의 경우와 마찬가지로 각 막대의 폭은 매개변수 width에 의해 조정된다. y=np.linspace(min(x)-1, max(x)+1, 10) y array([-4.48810153, -3.54351935, -2.59893717, -1.65435499, -0.70977282, 0.23480936, 1.17939154, 2.12397372, 3.0685559 , 4.01313807]) plt.hist(x, y, normed=True) plt.show()

R 미분과 적분

내용 expression 미분 2차 미분 mosaic를 사용한 미분 적분 미분과 적분 R에서의 미분과 적분 함수는 expression()함수에 의해 생성된 표현식을 대상으로 합니다. expression expression(문자, 또는 식) 이 표현식의 평가는 eval() 함수에 의해 실행됩니다. > ex1<-expression(1+0:9) > ex1 expression(1 + 0:9) > eval(ex1) [1] 1 2 3 4 5 6 7 8 9 10 > ex2<-expression(u, 2, u+0:9) > ex2 expression(u, 2, u + 0:9) > ex2[1] expression(u) > ex2[2] expression(2) > ex2[3] expression(u + 0:9) > u<-0.9 > eval(ex2[3]) [1] 0.9 1.9 2.9 3.9 4.9 5.9 6.9 7.9 8.9 9.9 미분 D(표현식, 미분 변수) 함수로 미분을 실행합니다. 이 함수의 표현식은 expression() 함수로 생성된 객체이며 미분 변수는 다음 식의 분모의 변수를 의미합니다. $$\frac{d}{d \text{변수}}\text{표현식}$$ 이 함수는 어떤 함수의 미분의 결과를 표현식으로 반환합니다. > D(expression(2*x^3), "x") 2 * (3 * x^2) > eq<-expression(log(x)) > eq expression(log(x)) > D(eq, "x") 1/x > eq2<-expression(a/(1+b*exp(-d*x))); eq2 expression(a/(1 + b * exp(-d * x))) > D(eq2, "x") a * (b * (exp(-d * x) * d))/(1 + b