Processing math: 100%
반응형

Intro


정규분포는 종모양을 띄는 분포로, 가장 익숙한 개념입니다. 이번 글에서는 정규분포와 정규성 검정에 대해서 정리하겠습니다.

정규분포


정규분포 (normal distribution, gaussian distribution)는 평균(μ)과 표준편차(σ)에 의해 모양이 결정되는 데이터 분포입니다.

따라서 확률 변수 X가 정규분포를 따르고 평균과 표준편차를 알 수 있으면, 각 x값이 발견될 확률을 아래의 식으로 구할 수 있습니다.

12πσe(xμ)22σ2

μ=0,σ=1인 특수한 경우의 정규분포를 표준 정규분포라고 합니다.

표준 정규분포를 따르지 않는 정규분포와 다른 분포들도 분포를 이루는 각 값에서 평균을 빼고, 표준편차로 나눔으로써 μ=0,σ=1인 상태로 변환할 수 있습니다.

이런 과정을 표준화(standardization)이라고 합니다.

이때 표준화된 분포의 각 값을 z-score라고 합니다.

z=xμσ

표준화는 분포의 모양을 바꾸지 않는 변환이기 때문에, 아래와 같은 목적으로 사용될 수 있습니다.

두 분포의 모양 비교
데이터 전처리 (scaling)
정규성 검정

정규성 검정


정규성 검정(normality test)은 주어진 분포가 정규분포를 따르는지 확인하기 위한 방법입니다. 이는 가설 검정 기법인 t-test, ANOVA가 검정하려는 데이터의 분포가 정규성을 갖는다는 가정하에 사용되기 때문에, 해당 방법들을 적용할 수 있는지 여부를 알기 위해서 사용됩니다.

정규성 검정을위한 첫번째 방법으로, Q-Qplot(Quantile-Quantile plot)이 있습니다. Q-Qplot은 두 분포가 얼마나 유사한지를 보여주는 일반적인 graphical method입니다.

이때 정규성검정을 하고자 하는 분포를 표준화한 뒤, 표준 정규분포와의 Q-Qplot을 그리면, 해당 분포가 정규분포를 갖는지 알 수 있습니다.

예시를 통해 확인해보겠습니다.

[code download]

# 표준정규분포의 Q-Q plot
std_normal = np.random.normal(loc=0, scale=1, size=20000) # 표준정규분포에서 데이터 샘플링, loc=평균, scale=편차

f, ax = plt.subplots(1,2, figsize=(10,5))
f.subplots_adjust(right=1)

sns.histplot(std_normal, ax=ax[0]) # 샘플링한 데이터의 분포
ax[0].set_title("Data distribution")
ax[0].set_xlabel("sample value")

stats.probplot(std_normal, dist="norm", plot=ax[1]) # Q-Q plot

plt.show()
f.savefig(f"{save_path}/qq_normal.png")

표준 정규분포에서 추출한 데이터의 분포와 그것의 Q-Qplot을 그리는 코드입니다. 결과는 아래와 같습니다.

2번째 그림의 빨간 선이 데이터가 완벽한 표준 정규분포를 가질 때의 값이고, 비교하고자 하는 분포의 데이터는 파란 점으로 표현되어 있습니다. 당연하게도 둘은 거의 일치하는 것을 알 수 있습니다.

이번에는 실제 세계의 데이터가 정규분포를 갖는지 확인해보겠습니다. [data download]

# AT&T회사의 일별 주가변동 정보의 Q-Qplot
sp500_px_df = pd.read_csv('data/sp500_data.csv') # S&P500에 있는 회사의 일별 주식 등락 정보
sp500_px_df.rename(columns={'Unnamed: 0': 'Dates'},inplace=True)

atnt = 'T'    # 회사 AT&T

times = list(range(300))
poisson = stats.poisson.pmf(times,mu=20)

f, ax = plt.subplots(1,2, figsize=(10,5))
f.subplots_adjust(right=1)

sns.histplot(sp500_px_df[atnt], ax=ax[0])
ax[0].set_title("Data distribution")
ax[0].set_xlabel("fluctuation")

stats.probplot(sp500_px_df[atnt], dist="norm", plot=ax[1])

plt.show()
f.savefig(f"{save_path}/qq_atnt.png")

위와 같이, 데이터가 중앙에 많이 몰려있고, 평균에서 멀어질수록 급격하게 데이터 수가 감소하는 분포를 Q-Qplot을 통해 보면, 양 끝에서 차이가 커짐을 알 수 있습니다. 따라서 이 데이터는 정규분포를 같는다고 보기 어렵겠네요.

정규성을 검정할 수 있는 다른 방법은 통계적 가설 검정을 이용한 방법이 있습니다.

이 방법은 우선 아래와 같이 가설을 설정합니다.

귀무가설(null hypothesis,H0): *"주어진 데이터는 정규분포를 따른다"*

대립 가설(alternative hypothesis, H1): *"주어진 데이터는 정규분포를 따르지 않는다"*

그다음 두 가설을 검정하기 위한 다양한 방법을 적용한 뒤, 검정 결과 p-value가 특정값보다 크면 귀무가설을 기각하지 않고 정규성을 갖는다고 보는 겁니다.

이런 통계적 가설 검정 방법은 여러 개가 있는데, 대표적으로 D'Agostino's K-squared test, Shapiro–Wilk test 등이 있습니다.

마무리


이번에는 정규분포와 정규성 검정에 대해서 정리해봤습니다!

이번 글을 쓰면서 matplotlib의 구조에 대해서 깊게 알게 되어 기쁘네요!

읽어주셔서 감사합니다~ 좋은 하루 보내세요!

 

References

선형대수와 통계학으로 배우는 머신러닝 with 파이썬

Wikipedia-Normality test

반응형

+ Recent posts