수학/베이지안 추론

베이즈 추론 명확하게 이해하기: 강아지 몸무게 추정 (3/3)

FedTensor 2025. 12. 9. 11:42

사전 지식과 믿음

In Reign’s case I do have additional information. I know that the last time I came to the vet she weighed in at 14.2 pounds. I also know that she doesn't feel noticeably heavier or lighter to me, although my arm is not a very sensitive scale. Because of this, I believe that she's about 14.2 pounds but might be a pound or two higher or lower. To represent this, I use a normal distribution with a peak at 14.2 pounds and with a standard deviation of a half pound.
 
위의 인용글로부터 사전 지식과 믿음을 추출하면 아래와 같습니다.
  • 사전 지식: 이전에 동물병원을 방문하였을 때 강아지의 측정 몸무게를 얻고 이를 토대로 추정한 몸무게는 14.2 파운드였습니다. 수십 번 측정하여 평균을 낸 값일 수도 있고 강아지를 움직이지 못하도록 한 상태에서 한 번 측정한 값일 수도 있습니다.
  • 믿음: 강아지를 팔로 안았을 때의 느낌으로는 그동안 실제 몸무게가 크게 변하지는 않은 듯합니다. 1 파운드나 2 파운드 정도의 차이는 있을 수 있습니다. 믿음의 정도를 수치화한다면 14.2 파운드를 평균으로 하고 0.5 파운드를 표준편차로 하는 정규분포입니다.
여기서는 믿음의 정도를 정규분포로 수치화하였지만 다른 형태의 분포로 수치화하는 것도 얼마든지 가능합니다. 특히 새롭게 얻은 사전 지식이 있다면 이를 적절히 수치화하여 믿음의 정도에 반영할 수 있습니다.
 
이러한 사전 지식과 믿음을 고려하면 이번 방문에서 얻은 측정 몸무게 중에서 17.5 파운드는 유효한 값이 아닐 가능성이 높습니다. 이 문제를 다루기 위하여 다음 두 가지 방법을 고려할 수 있습니다.
  1. 17.5 파운드를 버리고 나머지 두 개의 측정값에 대하여 평균을 구한다.
  2. 17.5 파운드를 버리기 보다는 낮은 가중치를 적용하고 이전의 몸무게와 비슷한 값들에 대해서는 높은 가중치를 적용하여 평균을 구한다.
아래 그래프는 강아지의 몸무게에 대해 얻은 사전 지식을 토대로 형성하게 된 실제 몸무게의 분포에 대한 믿음의 정도를 수치화한 것입니다. 이것은 실제 몸무게가 주어질 때 측정 몸무게의 확률분포를 나타내는 모델과는 무관합니다.
w_prior = 14.2
s_prior = 0.5

x = np.arange(10, 20, 0.1)
p_prior = stats.norm.pdf(x, w_prior, s_prior)

plt.plot(x, p_prior)
plt.vlines(w_prior, 0, 0.8, colors='c')
plt.grid(True)
plt.title('Prior probability distribution')
plt.xlabel('actual weight')
plt.ylabel('probability density')
plt.show()

믿음의 정도를 가중치로 활용

강아지의 실제 몸무게에 대한 우도를 계산할 때 실제 몸무게에 대한 믿음의 정도를 가중치로 활용할 수 있습니다.
w_actual_arr = [13.0, 14.5, 16.0]
weightings = stats.norm.pdf(w_actual_arr, w_prior, s_prior)

plt.plot(x, p_prior)
plt.plot(w_actual_arr, weightings, 'o')
plt.vlines(w_actual_arr, 0, 0.8, colors='m')
plt.title('weighting distribution')
plt.xlabel('actual weight')
plt.ylabel('weighting')
plt.grid(True)
plt.show()

이제 실제 몸무게와 관련하여 다음 세 가지는 같은 것을 지칭한다고 말할 수 있습니다.
  • 사전 확률 분포(Prior probability distribution)
  • 믿음의 정도 분포(Belief distribution)
  • 가중치 분포(Weighting distribution)
def plot_measured_weight_probability_density_with_weighting(w_actual, s_actual, weighting, w_measured_arr):
    x = np.arange(10, 20, 0.1)
    y = stats.norm.pdf(x, w_actual, s_actual)

    p_distribution = stats.norm.pdf(x, w_actual, s_actual)
    p_measured = stats.norm.pdf(w_measured_arr, w_actual, s_actual)

    plt.plot(x, p_distribution * weighting)
    plt.plot(w_measured_arr, p_measured * weighting, 'o')
    plt.grid(True)
    plt.title(f'actual weight: {w_actual:.1f} lb')
    plt.xlabel('measured weight')
    plt.ylabel('probability density * weighting')
    plt.ylim(0, 0.2)
    
plt.figure(figsize = (15, 4))

# subplot-1
w_actual = w_actual_arr[0]
weighting = weightings[0]

plt.subplot(131)
plot_measured_weight_probability_density_with_weighting(w_actual, s_actual, weighting, w_measured_arr)

# subplot-2
w_actual = w_actual_arr[1]
weighting = weightings[1]

plt.subplot(132)
plot_measured_weight_probability_density_with_weighting(w_actual, s_actual, weighting, w_measured_arr)

# subplot-3
w_actual = w_actual_arr[2]
weighting = weightings[2]

plt.subplot(133)
plot_measured_weight_probability_density_with_weighting(w_actual, s_actual, weighting, w_measured_arr)

plt.show()
 

실제 몸무게로 추정하는 값이 13.0, 14.5, 16.0 lb일 때 우도에 가중치를 적용하여 모두 곱함으로써 사후 확률값을 계산하고 이를 그래프로 그려서 시각적으로 비교해 봅니다.
  • 사후 확률값을 구하는 과정에서 측정값에 대한 Marginal Probability를 구해서 나누어야 하지만 관찰값 자체는 그대로 유지하면서 실제값으로 추정하는 값만 바꾸어 가면서 계산할 경우에는 Marginal Probability를 계산하지 않고 사전 확률값과 우도의 곱들의 상대적인 차이만을 구해서 비교하기도 합니다.
def get_posteriori(w_prior, s_prior, w_actual, s_actual, w_measured_arr):
    l_measured = stats.norm.pdf(w_measured_arr, w_actual, s_actual)
    weighting = stats.norm.pdf(w_actual, w_prior, s_prior)
    posteriori = np.prod(l_measured * weighting)
    return posteriori

w_actual_arr = [13.0, 14.5, 16.0]
posteriori_arr = []
    
for w_actual in w_actual_arr:
    posteriori = get_posteriori(w_prior, s_prior, w_actual, s_actual, w_measured_arr)
    posteriori_arr.append(posteriori)

plt.plot(w_actual_arr, posteriori_arr, 'o')
plt.xlim(10, 20)
plt.ylim(0, 0.1e-2)
plt.grid(True)
plt.title('Posterior probability distribution')
plt.xlabel('actual weight')
plt.show()

최대 사후 확률(Maximum A Posteriori, MAP)

실제 몸무게일 것이라고 추정하는 값을 더 다양하게 설정하고 사후확률 값의 분포를 그래프로 그려봅니다. 그러면 실제 몸무게가 어떤 값을 가질 때 사후확률값이 최대가 되는지 시각적으로 파악할 수 있습니다.
w_actual_arr = np.arange(10, 20, 0.02)
posteriori_arr = []
    
for w_actual in w_actual_arr:
    posteriori = get_posteriori(w_prior, s_prior, w_actual, s_actual, w_measured_arr)
    posteriori_arr.append(posteriori)

peak_location = w_actual_arr[np.argmax(posteriori_arr)]
print(f'Peak location: {peak_location:.1f}')

plt.figure(figsize = (12, 5))
plt.plot(w_actual_arr, posteriori_arr, label='posterior')
plt.vlines(w_measured_arr, 0, 0.12e-2, colors='r')
plt.xlim(10, 20)
plt.ylim(0, 0.12e-2)
plt.vlines(peak_location, 0, 0.12e-2, colors='c')
plt.grid(True)
plt.title('Posterior probability distribution')
plt.xlabel('actual weight')
plt.show()
Peak location: 14.3

위 그래프의 하늘색 직선은 실제 몸무게의 값이 14.3 파운드인 경우이고 이 때 사후확률 값은 최대가 됩니다. 따라서 MAP 방식으로 추정한 강아지의 몸무게는 14.3 파운드입니다.

정리

MLE는 MAP에서 weighting 값을 1로 준 경우에 해당합니다. 이것은 사전 지식을 고려하지 않기 때문에 실제 몸무게가 동일한 가능성으로 모든 값을 가질 수 있음을 나타냅니다. 따라서 MLE는 MAP의 특수한 경우라고 말할 수 있습니다.
  • 강아지의 측정 몸무게: 13.9 lb, 17.5 lb and 14.1 lb (평균값은 15.2 lb)
사전 지식이 없다면 MLE 방식을 사용하여 강아지의 실제 몸무게를 추정합니다.
  • MLE 방식으로 강아지의 실제 몸무게 추정: 15.2 lb
사전 지식을 가지고 있다면 이를 기반으로 하는 믿음을 수치화하고 MAP 방식을 사용하여 강아지의 실제 몸무게를 추정할 수 있습니다.
  • 강아지의 몸무게에 대한 사전 지식: 14.2 lb
  • 사전 지식에 기반한 믿음: 실제 몸무게의 확률 분포는 평균이 14.2 파운드이고 표준편차가 0.5인 정규분포를 따른다.
  • MAP 방식으로 강아지의 실제 몸무게 추정: 14.3 lb
강아지 몸무게에 대한 사전 지식이 있다고 하더라도 측정을 충분히 많이 하면 사전 지식의 영향이 상대적으로 작아지고 측정값들의 영향은 커집니다. 그러면 베이즈 추론의 결과는 빈도주의 통계의 최대 우도 추정의 결과와 사실상 같아집니다.