예제 1(우도가 작은 케이스)
다음 코드는 정규분포를 이용해 우도와 대수우도를 구한다.
[In]
# 우도가 작은 케이스
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
x_data = np.array([2.4, 1.2, 3.5, 2.1, 4.7]) # 넣어볼 데이터(특성 벡터)
y_data = np.zeros(5)
mu = 0 # 평균
sigma = 1 # 표준편차
# 정규분포의 확률밀도함수
def pdf(x, mu, sigma):
return 1/(sigma*np.sqrt(2*np.pi))*np.exp(-(x - mu)**2 / (2*sigma**2))
x_pdf = np.linspace(-5, 5, 1000)
y_pdf = pdf(x_pdf, mu, sigma)
plt.scatter(x_data, y_data)
plt.plot(x_pdf, y_pdf)
plt.title('Standard Normal Distribution')
plt.xlabel('x', size = 14)
plt.ylabel('y', size = 14)
plt.grid()
plt.show()
print(" 우도 ".center(20, '-'))
print(np.prod(pdf(x_data, mu, sigma)))
print(" 대수우도 ".center(20, '-'))
print(np.log(np.prod(pdf(x_data, mu, sigma))))
[Out]
-------- 우도 --------
1.0632480805734735e-12
------- 대수우도 -------
-27.569692666023364
데이터가 한쪽으로 치우쳐져 있어 우도와 대수우도가 매우 작은 것을 확인할 수 있다.
따라서 특성벡터(데이터)는 그다지 타당성 있지 않다.
예제2(우도가 큰 케이스)
[In]
# 우도가 큰 케이스
import numpy as np
import matplotlib.pyplot as plt
x_data = np.array([2.4, 1.2, 3.5, 2.1, 4.7])
y_data = np.zeros(5)
mu = np.average(x_data) # 특성벡터의 평균
sigma = np.std(x_data) # 특성벡터의 표준편차
# 정규분포의 확률밀도함수
def pdf(x, mu, sigma):
return 1/(sigma*np.sqrt(2*np.pi)) * np.exp(-(x-mu)**2/(2*sigma**2))
x_pdf = np.linspace(-3, 7, 1000)
y_pdf = pdf(x_pdf, mu, sigma)
plt.scatter(x_data, y_data)
plt.plot(x_pdf, y_pdf)
plt.xlabel('x', size = 14)
plt.ylabel('y', size = 14)
plt.grid()
plt.show()
print(' 우도 '.center(20, '-'))
print(np.prod(pdf(x_data, mu, sigma)))
print(' 대수우도 '.center(20, '-'))
print(np.log(np.prod(pdf(x_data, mu, sigma))))
[Out]
-------- 우도 --------
0.0003211757807192693
------- 대수우도 -------
-8.043521981227514
특성벡터(데이터)가 평균에 치우쳐져 있어 우도와 대수우도가 큰 것을 확인할 수 있다. 따라서 타당성이 높다.
실제로 정규분포의 파라미터(평균, 표준편차)가 특성벡터의 평균과 표준편차일 때, 특성벡터의 우도와 대수우도는 최대값을 갖는다. 다음 설명을 참고해보자.
아래 코드에서는 정규분포의 평균을 특성벡터의 평균으로 고정시키고 표준편차만 바꾸어가며 데이터의 대수우도를 살펴본다.
[In]
# 우도와 파라미터의 관계
import numpy as np
import matplotlib.pyplot as plt
x_data = np.array([2.4, 1.2, 3.5, 2.1, 4.7]) # 특성벡터(데이터)
mu = np.average(x_data) # 데이터의 평균값
sigma = np.std(x_data) # 데이터의 표준편차
# 정규분포의 확률밀도함수
def pdf(x, mu, sigma):
return 1/(sigma*np.sqrt(2*np.pi)) * np.exp(-(x-mu)**2/(2*sigma**2))
# 대수우도
def log_likelyhood(p):
return np.sum(np.log(p))
x_sigma = np.linspace(0.5, 8, 1000) # 가로축으로 사용하는 표준편차
y_loglike = [] # 세로축에 사용하는 대수우도
for s in x_sigma:
log_like = log_likelyhood(pdf(x_data, mu, s))
y_loglike.append(log_like)
plt.plot(x_sigma, np.array(y_loglike)) # 표준편차에 따른 대수우도 변화 그리기
plt.plot([sigma, sigma], [min(y_loglike), max(y_loglike)], linestyle = 'dashed') # 데이터의 표준편차 위에 세로선 긋기
plt.xlabel('x', size = 14)
plt.ylabel('y', size = 14)
plt.grid()
plt.show()
[Out]
위 결과와 같이 특성벡터의 표준편차일 때, 대수우도가 가장 큰 것을 확인할 수 있다.