평균을 중심으로 좌우가 대칭인 분포를 의미합니다.
이 분포의 밀도함수는 다음과 같습니다.
$$ \text{f(x)} = \frac{1}{\sigma \sqrt{2 \pi}} \text{exp}(-\frac{(x-\mu)^2}{2\sigma^2})$$
이 밀도함수을 기본으로 다음과 같이 정규분포그래프를 작성할 수 있습니다.
우선 밀도함수를 산출하는 함수는
def normalFunS(x, mu,sd):
a=1/(sd*np.sqrt(2*np.pi))
b=np.exp(-(x-mu)**2/(2*sd**2))
return(a*b)
>>> import numpy as np
>>> import pandas as pd
>>> import matplotlib.pyplot as plt
>>> from scipy import stats
>>> x=np.random.randn(10000,1)
>>> n, bins, ig=plt.hist(x, bins=50, normed=True)
>>> mu=np.mean(x)
>>> sd=np.std(x)
>>> plt.plot(bins, normalFunS(bins, mu, sd), linewidth=2, color="r")
>>> plt.show()
이 그래프의 정규성은 scipy모듈의 stats 클래스의 함수 normaltest()를 사용하여 검사할 수 있습니다.
scipy.stats.normaltest(x, axis=0):
객체(x)가 정규분포에 부합하는가를 검정합니다. 즉,
H0: 이 객체는 정규분포를 따른다.
이 검정은 첨도(kurtosis)와 왜도(skew)를 결합하여 검정합니다.
매개변수 axis=0(column), 1(row)를 지정하는 것으로 열이 기본값입니다.
>>> stats.normaltest(x)
NormaltestResult(statistic=array([ 0.93501267]), pvalue=array([ 0.62656276]))
위의 결과는 pvalue>>0.05이므로 귀무가설을 기각할 수 없으므로 객체 x는 정규분포를 따른다고 할 수 있습니다.
위 객체의 기술통계량은 stats.dexcribe() 함수에 의해 알아볼 수 있습니다.
>>> stats.describe(x)
DescribeResult(nobs=10000, minmax=(array([-3.61958797]), array([ 3.67668265])), mean=array([-0.00329405]), variance=array([ 1.00511116]), skewness=array([-0.02051491]), kurtosis=array([-0.02508243]))
위의 결과는 자료수, 객체의 최소값, 최대값, 평균, 분산, 왜도, 첨도를 반환합니다.
위의 정규성 검정은 왜도와 첨도를 근거로 합니다. 그러면 각각의 검정결과를 알아볼까요?
왜도는 분포의 뒤틀림 즉, 대칭성의 판단을 위한 값으로 정규분포의 경우 skew=0입니다.
skew >0 인 경우 는 분포가 오른쪽 꼬리가 두터워짐을 의미하고 반대의 경우는 왼쪽 꼬리에 큰 가중치가 있음을 나타냅니다.
skew test는 왜도 값이 0에 충분히 가까운지를 판단하는 것입니다.
H0: skew=0 즉, 정규분포에 부합한다.
>>> stats.skew(x) #왜도
array([-0.02051491])
>>> stats.skewtest(x) #왜도 검정
SkewtestResult(statistic=array([-0.83805683]), pvalue=array([ 0.40199879]))
첨도는 표준편차에 의해 나누어진 4번째 중앙 모멘트입니다.
정규분포에 대한 첨도의 값은 두가지가 적용됩니다.
Fisher's definition : kurtosis=0.0
Pearson's definition : kurtosis=3.0
그러므로 다음의 첨도를 위한 함수의 매개변수 fisher를 True로 전달할 경우 0.0, False일 경우 3.0이 적용됩니다.
stats.kurtosis(obj, axis=0, fisher=True, bias=True)
매개변수 bias=False일 경우 편재된 모멘트 추정량(biased moment estimators)로 부터 bias를 제거하기 위해 k statistics를 이용하여 계산됩니다.
>>> stats.kurtosis(x) #첨도
Out[58]: array([-0.02508243])
H0: 정규분포에 부합
>>>stats.kurtosistest(x)
Out[60]: KurtosistestResult(statistic=array([-0.48236233]), pvalue=array([ 0.62954857]))
위에서 정규확률밀도 함수에 대한 사용자 정의함수를 생성하여 사용하였습니다. 그러나
scipy 모듈에서는 표준정규분포등의 각 분포의 확률밀도함수와 누적확률밀도 함수를 산출하는 함수를 제공합니다.
--ppf(alpha, loc=0, scale=1) : percent point function으로 각 분포에서 알파값(확률값)에 대응하는 값을 반환합니다.
--pdf(value, loc=0, scale=1): 분포에서 값에 대응하는 확률밀도 함수 (확률)값을 반환
--cdf(value, loc=0, scale=1): 분포에서 값에 대응하는 누적확률밀도 함수 (확률)값을 반환
--interval(alpha, loc=0, scale=1) : 분포에서 알파값에 대응하는 신뢰구간을 반환합니다.
위함수에서 loc는 평균, scale=1은 표준편차로서 각각 0, 1이 기본값입니다.
>>> x=stats.norm.ppf(0.95) #확률 0.95 대응되는 정규분포상에서 값
>>> x
1.6448536269514722
>>> stats.norm.pdf(x, 0, 1) #정규확률밀도
0.10313564037537139
>>> stats.norm.cdf(x, 0, 1) #누적확률밀도값으로 정규분포에서 x축의 값1.644..에 대응되는 그래프의 면적 합이다. 위 x에 주어진 확률값과 같다.
Out[89]: 0.94999999999999996
다음 interval()에 의한 결과는 ppf로 부터 계산할 수 있다. 그러나 이 값은 양측검정을 위한 것으로 확률값 0.95라면 전체 면적중 0.95에 대응되는 정규분포상의 x축값을 반환한다.
정규분포는 평균을 중심으로 양쪽이 대칭되므로 왼쪽 끝으로 부터 0.25, 오른쪽 끝으로 부터 0.25를 뺀 모든 부분을 의미하므로 아래의 결과는 그 아래 코드에서 인자로 전달한 0.975에 대응하는 값이 됩니다.
>>> stats.norm.interval(0.95)
(-1.959963984540054, 1.959963984540054)
>>> stats.norm.ppf(0.975)
1.959963984540054
다음은 t분포에서의 구간을 반환합니다. t분포의 경우는 df(자유도)값을 인자로 전달해야 합니다.
stats.t.interval(0.95, 100)
Out[92]: (-1.9839715184496334, 1.9839715184496334)
scipy 모듈에서는 표준정규분포등의 각 분포의 확률밀도함수와 누적확률밀도 함수를 산출하는 함수를 제공합니다.
--ppf(alpha, loc=0, scale=1) : percent point function으로 각 분포에서 알파값(확률값)에 대응하는 값을 반환합니다.
--pdf(value, loc=0, scale=1): 분포에서 값에 대응하는 확률밀도 함수 (확률)값을 반환
--cdf(value, loc=0, scale=1): 분포에서 값에 대응하는 누적확률밀도 함수 (확률)값을 반환
--interval(alpha, loc=0, scale=1) : 분포에서 알파값에 대응하는 신뢰구간을 반환합니다.
위함수에서 loc는 평균, scale=1은 표준편차로서 각각 0, 1이 기본값입니다.
>>> x=stats.norm.ppf(0.95) #확률 0.95 대응되는 정규분포상에서 값
>>> x
1.6448536269514722
>>> stats.norm.pdf(x, 0, 1) #정규확률밀도
0.10313564037537139
>>> stats.norm.cdf(x, 0, 1) #누적확률밀도값으로 정규분포에서 x축의 값1.644..에 대응되는 그래프의 면적 합이다. 위 x에 주어진 확률값과 같다.
Out[89]: 0.94999999999999996
다음 interval()에 의한 결과는 ppf로 부터 계산할 수 있다. 그러나 이 값은 양측검정을 위한 것으로 확률값 0.95라면 전체 면적중 0.95에 대응되는 정규분포상의 x축값을 반환한다.
정규분포는 평균을 중심으로 양쪽이 대칭되므로 왼쪽 끝으로 부터 0.25, 오른쪽 끝으로 부터 0.25를 뺀 모든 부분을 의미하므로 아래의 결과는 그 아래 코드에서 인자로 전달한 0.975에 대응하는 값이 됩니다.
>>> stats.norm.interval(0.95)
(-1.959963984540054, 1.959963984540054)
>>> stats.norm.ppf(0.975)
1.959963984540054
다음은 t분포에서의 구간을 반환합니다. t분포의 경우는 df(자유도)값을 인자로 전달해야 합니다.
stats.t.interval(0.95, 100)
Out[92]: (-1.9839715184496334, 1.9839715184496334)
댓글
댓글 쓰기