Dive into Deep Learning
Dive into Deep Learning

2.6. 확률과 통계

머신 러닝은 어떤 방식이든지 결국 예측을 수행하는 것입니다. 어떤 환자의 의료 기록을 바탕으로 내년에 심장 마비를 겪을 확률 예측하기를 예로 들어볼 수 있습니다. 비정상 탐지를 위해서, 비행기 제트 엔진의 센서 데이터가 정상적으로 동작할 때 어떤 값을 갖게 될지 예측을 할 수도 있습니다. 강화학습에서는 에이전트가 주어진 환경에서 똑똑하게 동작하게 만드는 것이 목표입니다. 이 경우에는 주어진 행동들 중에 가장 높은 보상을 받는 확률을 고려해야합니다. 추천 시스템을 만드는 경우에도 확률을 고려해야합니다. 예를 들어 여러분이 대형 온라인 서점에서 일을 한다면, 어떤 책을 홍보했을 때 특정 사용자가 그 책을 구매할지에 대한 확률을 추정하고 싶어할 것입니다. 이를 위해서 우리는 확률과 통계의 언어를 사용할 필요가 있습니다. 확률을 다루는 별도의 과정, 전공, 논문, 직업 심지어는 부서까지도 있습니다. 이 책의 목표는 이 모든 주제들에 대해서 배워보는 것은 아니고, 여러분이 스스로 머신 러닝 모델을 만들 수 있을 정도의 내용을 알려주고, 이후에 스스로 공부해 볼 수 있는 주제들을 선택할 수 있도록 하는 것입니다.

지금까지 확률에 대해서 많이 이야기를 해왔지만, 확률에 정확하게 무엇인지를 설명하지 않았고 구체적인 예제를 들지는 않았습니다. 동물의 사진이 주어졌을 때, 고양이인지 개인지를 구분하는 문제를 조금 자세하게 살펴 보겠습니다. 이 문제는 간단해 보이지만, 사실 쉽지 않은 문제가 있습니다. 우선은 문제의 난이도가 이미지의 해상도에 따라 차이가 있을 수 있습니다.

10px 20px 40px 80px 160px
image0 image1 image2 image3 image4
image5 image6 image7 image8 image9

사람이 320 픽셀 해상도의 이미지에서 개와 고양이를 구분하는 것은 쉽습니다. 하지만, 40 픽셀이 되면 그 분류가 어렵고, 10픽셀로 줄어들면 거의 불가능합니다. 즉, 개와 고양이를 먼 거리에서 판별하는 것은 (또는 낮은 해상도의 이미지에서) 동전 던지기를 해서 추측하는 것과 동일해집니다. 확률은 확실성에 대한 추론을 하는 공식적인 방법을 제공합니다. 만약, 이미지에 고양이가 있다는 것을 완벽하게 확신한다면, 해당 레이블 \(l\) 이 고양이일 확률, \(P(l=\mathrm{cat})\) 는 1.0이라고 말합니다. 만약 \(l =\mathrm{cat}\) 인지 \(l = \mathrm{dog}\) 에 대한 아무런 판단을 못한다면, 두 확률은 동일하다고 하다고 말하며, \(P(l=\mathrm{cat}) = 0.5\) 이 됩니다. 만약 이미지에 고양이가 있다는 것을 확실하지는 않지만 어느 정도 확신한다면, 확률은 \(.5 < P(l=\mathrm{cat}) < 1.0\) 로 주어질 것입니다.

이제 두번째 예를 들어보겠습니다. 대만 날씨에 대한 데이터를 관찰한 데이터가 있을 때, 내일 비가 내릴 확률을 예측하고자 합니다. 여름인 경우에는 비가 내릴 확률이 \(0.5\) 정도가 될 것입니다. 위 두가지 예제 모두 살펴볼 가치가 있습니다. 두 경우 모두 결과에 대한 불확실성이 있지만, 주요 차이점이 있습니다. 첫번째 예제는 이미지가 고양이인지 개이지만, 우리가 어떤 것인지 모르는 경우이고, 두번째 예제는 결과가 실제로 임의로 일어나는 이벤트일 수도 있습니다. 즉, 확률이란 우리의 확실성에 대한 사고를 하기 위한 유연한 언어이며, 다양한 경우에 효과적으로 적용될 수 있습니다.

2.6.1. 기초 확률 이론

주사위를 던져서 다른 숫자가 아닌 1일 나오는 확률이 얼마나 되는지 찾는 경우를 생각해보겠습니다. 주사위가 공정하다면, 모든 6개 숫자들, \(\mathcal{X} = \{1, \ldots, 6\}\), 은 일어날 가능성이 동일합니다. 학술 용어로는 “1은 확률 \(\frac{1}{6}\) 로 일어난다”라고 말합니다.

공장에서 막 만들어진 주사위에 대해서 우리는 이 비율을 알지 못할 수 있고, 주사위가 공정한지 확인해야할 필요가 있습니다. 주사위를 조사하는 유일한 방법은 여러 번 던져보면서 결과를 기록하는 것입니다. 주사위를 던질 때마다, 우리는 \(\{1, 2, \ldots, 6\}\)에 하나의 숫자를 얻게 되고, 이 결과들이 주어지면, 각 숫자들이 일어날 수 있는 확률을 조사할 수 있습니다.

가장 자연스러운 방법은 각 숫자들이 나온 횟수를 전체 던진 횟수로 나누는 것입니다. 이를 통해서 우리는 특정 이벤트에 대한 확률을 추정 합니다. 큰 수의 법칙(the law of large numbers)에 따라, 던지는 횟수가 늘어날 수록 이 추정은 실제 확률과 계속 가까워집니다. 더 자세한 논의를 하기 전에, 실제로 실험을 해보겠습니다.

우선 필요한 패키지들을 import 합니다.

[1]:
import mxnet as mx
from mxnet import nd

다음으로는 주사위를 던지는 것을 해야합니다. 통계에서는 확률 분포에서 샘플을 뽑는 것을 샘플링 이라고 합니다. 연속되지 않은 선택들에 확률이 부여된 분포를 우리는 다항(multinomial) 분포라고 합니다. 분포(distribution) 에 대한 공식적인 정의는 다음에 다루겠고, 지금은 분포를 이벤트들에 확률을 할당하는 것 정도로 생각하겠습니다. MXNet에서 nd.random.multinomial 함수를 이용하면 다항 분포에서 샘플을 추출할 수 있습니다.

[2]:
probabilities = nd.ones(6) / 6
nd.random.multinomial(probabilities)
[2]:

[3]
<NDArray 1 @cpu(0)>

여러 샘플을 뽑아보면, 매번 임의의 숫자를 얻는 것을 확인할 수 있습니다. 주사위의 공정성을 추정하는 예제에서 우리는 같은 분포에서 많은 샘플을 추출하기를 원합니다. Python의 for loop을 이용하면 너무 느리기 때문에, random.multinomial 이 여러 샘플을 한번째 뽑아주는 기능을 이용해서 우리가 원하는 모양(shape)의 서로 연관이 없는 샘플들의 배열을 얻겠습니다.

[3]:
print(nd.random.multinomial(probabilities, shape=(10)))
print(nd.random.multinomial(probabilities, shape=(5,10)))

[3 4 5 3 5 3 5 2 3 3]
<NDArray 10 @cpu(0)>

[[2 2 1 5 0 5 1 2 2 4]
 [4 3 2 3 2 5 5 0 2 0]
 [3 0 2 4 5 4 0 5 5 5]
 [2 4 4 2 3 4 4 0 4 3]
 [3 0 3 5 4 3 0 2 2 1]]
<NDArray 5x10 @cpu(0)>

이제 주사위를 던지는 샘플을 구하는 방법을 알았으니, 100번 주사위를 던지는 시뮬레이션을 해서, 각 숫자들이 나온 횟수를 카운팅합니다.

[4]:
rolls = nd.random.multinomial(probabilities, shape=(1000))
counts = nd.zeros((6,1000))
totals = nd.zeros(6)
for i, roll in enumerate(rolls):
    totals[int(roll.asscalar())] += 1
    counts[:, i] = totals

1000번을 던져본 후에 최종 합계를 확인합니다.

[5]:
totals / 1000
[5]:

[0.167 0.168 0.175 0.159 0.158 0.173]
<NDArray 6 @cpu(0)>

결과에 따르면, 모든 숫자 중에 가장 낮게 추정된 확률은 약 \(0.15\) 이고, 가장 높은 추정 확률은 \(0.188\) 입니다. 공정한 주사위를 사용해서 데이터를 생성했기 때문에, 각 숫자들은 \(1/6\)\(0.167\) 의 확률을 갖는다는 것을 알고 있고, 예측도 매우 좋게 나왔습니다. 시간이 지나면서 이 확률이 의미 있는 추정치로 어떻게 수렴하는지를 시각해 볼 수도 있습니다.

이를 위해서 우선은 (6, 1000) 의 모양(shape)을 갖는 counts 배열을 살펴봅시다. 1000번을 수행하는 각 단계마다, counts 는 각 숫자가 몇 번 나왔는지를 알려줍니다. 그렇다면, counts 배열의 \(j\) 번째 열의 그때까지 던진 총 횟수로 표준화해서, 그 시점에서의 추정 확률 current 를 계산합니다. counts 객체는 다음과 같습니다.

[6]:
counts
[6]:

[[  0.   0.   0. ... 165. 166. 167.]
 [  1.   1.   1. ... 168. 168. 168.]
 [  0.   0.   0. ... 175. 175. 175.]
 [  0.   0.   0. ... 159. 159. 159.]
 [  0.   1.   2. ... 158. 158. 158.]
 [  0.   0.   0. ... 173. 173. 173.]]
<NDArray 6x1000 @cpu(0)>

던진 총 횟수로 표준화 하면,

[7]:
x = nd.arange(1000).reshape((1,1000)) + 1
estimates = counts / x
print(estimates[:,0])
print(estimates[:,1])
print(estimates[:,100])

[0. 1. 0. 0. 0. 0.]
<NDArray 6 @cpu(0)>

[0.  0.5 0.  0.  0.5 0. ]
<NDArray 6 @cpu(0)>

[0.1980198  0.15841584 0.17821783 0.18811882 0.12871288 0.14851485]
<NDArray 6 @cpu(0)>

결과에서 보이듯이, 주사위를 처음 던진 경우 하나의 숫자에 대한 확률이 \(1.0\) 이고 나머지 숫자들에 대한 확률이 \(0\) 인 극단적인 예측을 하지만, 100번을 넘어서면 결과가 상당히 맞아 보입니다. 플롯을 그리는 패키지 matplotlib 을 이용해서 이 수렴 과정을 시각화 해봅니다. 이 패키지를 아직 설치하지 않았다면, install it 를 참고해서 지금 하세요.

[8]:
%matplotlib inline
from matplotlib import pyplot as plt
from IPython import display
display.set_matplotlib_formats('svg')

plt.figure(figsize=(8, 6))
for i in range(6):
    plt.plot(estimates[i, :].asnumpy(), label=("P(die=" + str(i) +")"))

plt.axhline(y=0.16666, color='black', linestyle='dashed')
plt.legend()
plt.show()
../_images/chapter_crashcourse_probability_15_0.svg

각 선은 주사위의 숫자 중에 하나를 의미하고, 1000번 주사위 던지기를 수행하면서 각 횟수마다 각 숫자가 나올 확률의 추정값을 나타내는 그래프입니다. 검은 점선은 진짜 확률(true probability, \(1/6\))을 표시합니다. 횟수가 늘어가면 선들이 진짜 확률에 수렴하고 있습니다.

주사위 던지기 예를 통해서 확률 변수(random variable)라는 개념을 소개했습니다. 여기서 \(X\) 로 표현할 확률 변수는 어떤 양이 될 수 있고, 결정적이지 않을 수 있습니다. 확률 변수는 여러 가능성들의 집합에서 하나의 값을 나타낼 수도 있습니다. 집합은 괄호를 이용해서 표현합니다. 예를 들면, \(\{\mathrm{cat}, \mathrm{dog}, \mathrm{rabbit}\}\) 입니다. 집합에 속한 아이템들은 원소(element) 라고 하고, 어떤 원소 \(x\) 가 집합 \(S\)속한다 라고 하면 표기는 \(x \in S\) 로 합니다. 기호 \(\in\) 는 “속한다”라고 읽고, 포함 관계를 표현합니다. 예를 들어, \(\mathrm{dog} \in \{\mathrm{cat}, \mathrm{dog}, \mathrm{rabbit}\}\) 입니다. 주사위 던지는 것의 경우, 확률 변수 \(X \in \{1, 2, 3, 4, 5, 6\}\) 입니다

연속적이지 않은 확률변수(예를 들어 주사위의 6면)와 연속적인 확률변수(예를 들어 사람의 몸무게나 키) 사이에는 미묘한 차이점이 있다는 것을 기억하세요. 두 사람의 키가 정확하게 같은지를 묻는 경우는 드물 것입니다. 아주 정확한 측정 방법이 있어서 이를 적용한다면, 이 세상에 키가 완전하게 같은 사람 두사람이 없습니다. 사실, 적당히 정교한 측정을 하는 경우에도 아침에 일어났을 때의 키와 밤에 잠자기 전에 잰 키는 다르게 나옵니다. 즉, 어떤 사람의 키가 \(2.00139278291028719210196740527486202\) 미터일 확률을 물어보는 것은 의미가 없습니다. 전체 인구에 대해서도 이 확률은 거의 \(0\) 입니다. 따라서, 어떤 사람의 키가 어느 구간(예를 들면 1.99 와 2.01 미터 사이)에 속하는지를 묻는 것이 더 의미가 있습니다. 이런 경우들에는 우리는 어떤 값을 밀도(density)로 볼 가능성을 정량화 합니다. 정확하게 2.0미터인 키에 대한 확률은 없지만, 밀도는 0이 아닙니다. 서로 다른 두 키의 구간에 대해서는 확률값이 0이 아닌 수가 됩니다.

기억해 두어야할 몇가지 중요한 확률에 대한 공리(axiom)들이 있습니다.

  • 어떤 이벤트 \(z\) 에 대해서, 확률은 절대로 음수가 아닙니다. 즉, \(\Pr(Z=z) \geq 0\)
  • 두 이벤트 \(Z=z\)\(X=x\) 에 대해서, 두 이벤트의 합집합(union)에 대한 확률은 각 이벤트의 확률의 합보다 클 수 없습니다. 즉, \(\Pr(Z=z \cup X=x) \leq \Pr(Z=z) + \Pr(X=x)​\).
  • 어떤 확률 변수에 대해서, 모든 값들에 대한 확률의 합은 항상 1입니다. 즉, \(\sum_{i=1}^n \Pr(Z=z_i) = 1\).
  • 서로 겹치지 않는 두 사건, \(Z=z\)\(X=x\), t,에 대해서, 둘 중에 한 사건이 일어날 확률은 각 사건의 확률의 합과 같습니다. 즉, \(\Pr(Z=z \cup X=x) = \Pr(Z=z) + \Pr(X=x)\).

2.6.2. 여러 확률 변수 다루기

종종 하나 이상의 확률 변수를 동시에 다룰 필요가 생깁니다. 질병과 증상의 관계를 모델링하는 경우를 들 수 있습니다. 질병과 증상이 주어졌을 때, 예를 들면 ‘독감’과 ’기침’, 두개는 어떤 확률로 환자에게 일어날 수도 일어나지 않을 수 있습니다. 이 둘에 대한 확률이 작기를 기대하지만, 더 좋은 의료 처방을 할 수 있도록 확률과 둘 사이의 관계를 예측하고자 합니다.

더 복잡한 예로, 수백만 픽셀로 이루어진 이미지를 들어보겠습니다. 즉, 수백만 확률 변수가 존재합니다. 많은 경우에 이미지들은 이미지에 있는 객체를 지칭하는 레이블을 갖습니다. 이 레이블도 확률 변수로 생각할 수 있습니다. 더 나아가서는, 위치, 시간, 구경(apeture), 초점 거리, ISO, 초점, 카메라 종류 등 과 같은 모든 메타 데이터를 확률 변수로 생각할 수도 있습니다. 이 모든 것은 연관되어 발생하는 확률 변수들입니다. 여러 확률 변수를 다룰 때 몇가지 중요한 것들이 있습니다. 첫번째는 교차 확률 분포 \(\Pr(A, B)\) 입니다. 두 원소 \(a\)\(b\) 가 주어졌을 때, 교차 확률 분포는 동시에 \(A=a\) 이고 \(B=b\) 일 확률이 얼마인지에 대한 답을 줍니다. 임의의 값 \(a\)\(b\) 에 대해서, \(\Pr(A,B) \leq \Pr(A=a)\) 이라는 사실은 쉽게 알 수 있습니다.

\(A\)\(B\) 가 일어났기 때문에, \(A\) 가 발생하고, \(B\) 또한 발생해야 합니다. (또는 반대로). 즉, \(A\)\(B\) 가 동시에 일어나는 것은 \(A\)\(B\) 가 별도로 일어나는 것보다는 가능성이 낮습니다. 이 사실로 흥미로운 비율을 정의할 수 있습니다. 즉, \(0 \leq \frac{\Pr(A,B)}{\Pr(A)} \leq 1\). 우리는 이것을 조건부 확률(conditional probability) 이라고 부르며, \(\Pr(B | A)\) 로 표현합니다. 다시 말하면, \(A\) 가 일어났을 때 \(B\) 가 일어날 확률입니다.

조건부 확률의 정의를 이용하면, 확률에서 가장 유용하고 유명한 방정식을 도출할 수 있는데, 이것이 바로 베이즈 이론(Bayes’ theorem)입니다. 이를 도출하는 방법으로 \(\Pr(A, B) = \Pr(B | A) \Pr(A)\) 로부터 출발합니다. 대칭성을 적용하면, \(\Pr(A,B) = \Pr(A | B) \Pr(B)\) 이 돕니다. 조건 변수들 중 하나에 대해서 풀어보면 다음 공식을 얻게 됩니다.

\[\Pr(A | B) = \frac{\Pr(B | A) \Pr(A)}{\Pr(B)}\]

어떤 것으로부터 다른 어떤 것을 추론(즉 원인과 효과)하고자 하는데, 반대 방향에 대한 것만 알고 있을 경우에 아주 유용합니다. 주변화(marginalization)는 이것이 작동하게 만드는데 아주 중요한 연산입니다. 이 연산은 \(\Pr(A,B)\) 로 부터 \(\Pr(A)\)\(\Pr(B)\) 를 알아내는 연산입니다. \(A\) 가 일어날 확률은 모든 \(B\)에 대한 교차 확률(joint probability)의 값으로 계산됩니다. 즉,

\[\Pr(A) = \sum_{B'} \Pr(A,B') \text{ and } \Pr(B) = \sum_{A'} \Pr(A',B)​\]

점검해야 할 아주 유용한 특성은 종속독립 입니다. 독립은 하나의 사건의 발생이 다른 사건의 발생에 영향을 주지 않는 것을 의미합니다. 위 경우에는 \(\Pr(B | A) = \Pr(B)\) 를 의미합니다. 그 외의 경우들은 \(A\)\(B\)가 종속적이라고 합니다. 주사위를 두 번 연속으로 던지는 것은 독립적이나, 방의 전등 스위치의 위치와 방의 밝기는 그렇지 않습니다. (이 둘이 완전히 결정적이지는 않습니다. 왜냐하면, 전구가 망가질 수도 있고, 전원이 나갈 수도 있고, 스위치가 망가질 경우 등이 있기 때문입니다.)

그럼 배운 것을 테스트해보겠습니다. 의사가 환자에게 AIDS 테스트를 하는 것을 가정하겠습니다. 이 테스트는 상당히 정확해서, 환자가 음성일 경우 이를 틀리게 예측하는 확률이 1%이고, 환자가 양성일 경우 HIV 검출을 실패하지 않습니다. \(D\) 는 진단 결과를 \(H\) 는 HIV 상태를 표기합니다. \(\Pr(D | H)\) 결과를 표로 만들어보면 다음과 같습니다.

결과 HIV 양성 HIV 음성
테스트 결과 - 양성 1 0.01
테스트 결과 - 음성 0 0.99

같은 열의 값을 더하면 1이나, 행으로 더하면 그렇지 않습니다. 그 이유는 조건부 확률도 합이 확률처럼 1이여야하기 때문입니다. 테스트 결과가 양성일 경우 환자가 AIDS에 결렸을 확률을 계산해보겠습니다. 당연하게 도 이는 질병이 얼마나 일반적인가에 따라 달라집니다. 인구의 대부분이 건강하다고 가정하겠습니다. 즉 \(\Pr(\text{HIV positive}) = 0.0015\). 베이즈 이론(Bayes’ Theorem)을 적용하기 위해서 우리는 다음을 결정해야합니다.

\[\begin{split}\begin{aligned} \Pr(\text{Test positive}) =& \Pr(D=1 | H=0) \Pr(H=0) + \Pr(D=1 | H=1) \Pr(H=1) \\ =& 0.01 \cdot 0.9985 + 1 \cdot 0.0015 \\ =& 0.011485 \end{aligned}\end{split}\]

따라서, 우리가 얻는 것은 다음과 같습니다.

\[\begin{split}\begin{aligned} \Pr(H = 1 | D = 1) =& \frac{\Pr(D=1 | H=1) \Pr(H=1)}{\Pr(D=1)} \\ =& \frac{1 \cdot 0.0015}{0.011485} \\ =& 0.131 \end{aligned}\end{split}\]

이 결과는 99% 정확도로 테스트 결과가 양성으로 나올지라도 환자가 실제로 AIDS에 걸렸을 확률은 13.1% 밖에 되지 않는 다는 것을 의미입니다. 이 결과에서 보듯이, 통계는 매우 직관적이지 않을 수 있습니다.

2.6.3. 조건부 독립성

그렇다면, 환자가 이렇게 무서운 결과를 받았을 때 어떻게 해야할까요? 아마도 환자는 의사에게 테스트를 다시 해봐달라고 요청할 것입니다. 두번째 테스트는 다르게 나왔다고 하겠습니다. (즉, 첫번째 만큼 좋지 않습니다.)

결과 HIV 양성 HIV 음성
테스트 결과 - 양성 0.98 0.03
테스트 결과 - 음성 0.02 0.97

안타깝게도 두번째 테스트 역시 양성으로 나오고 있습니다. 베이즈 이론(Bayes’ Theorom)을 적용하기 위한 필요한 확률값들을 계산해봅니다.

  • \(\Pr(D_1 = 1 \text{ and } D_2 = 1) = 0.0003 \cdot 0.9985 + 0.98 \cdot 0.0015 = 0.00176955\)
  • \(\Pr(H = 1 | D_1 = 1 \text{ and } D_2 = 1) = \frac{0.98 \cdot 0.0015}{0.00176955} = 0.831\)

즉, 두번째 테스트 결과는 좋지 않다는 것에 더 확신하게 만듭니다. 두번째 결과는 첫번째 보다 덜 정확함에도 불구하고, 예측 결과를 더 향상시켰습니다. 그렇다면, 첫번째 테스트를 두번하지 않을까요? 결국, 첫번째 테스트가 더 정확했습니다. 두번째 테스트가 필요한 이유는 첫번째 테스트를 독립적으로 확인하기 위함입니다. 즉, \(\Pr(D_1, D_2 | H) = \Pr(D_1 | H) \Pr(D_2 | H)\) 이라는 암묵적인 가정을 했습니다. 통계학에서는 이런 확률 변수를 조건에 독립적이라고 하며, \(D_1 \perp\!\!\!\perp D_2 | H\) 라고 표현합니다.

2.6.4. 요약

이 절에서 우리는 확률, 독립, 조건 독립, 그리고 기본적인 결론을 도출하는데 이것들을 어떻게 사용하는지를 알아봤습니다. 이 개념들은 아주 유용합니다. 다음 절에서는 나이브 베이즈 분류기(Naive Nayes)를 사용한기본적인 예측을 하는데 이 개념들이 어떻게 사용되는지 살펴보겠습니다.

2.6.5. 문제

  1. \(\Pr(A)\)\(\Pr(B)\) 확률로 두 사건이 주어졌을 때, \(\Pr(A \cup B)\)\(\Pr(A \cap B)\) 의 상한과 하한을 구하세요. 힌트 - Venn Diagram을 사용하는 상황을 그려보세요.
  2. 연속적인 사건, 즉 \(A\), \(B\), \(C\), 들이 있는데, \(B\)\(A\)에만 의존하고, \(C\)\(B\)에만 의존한다고 가정합니다. 이 경우 교차 확률(joint probability)를 간단하게 할 수 있을까요? 힌트 - 이는 Markov Chain 입니다.

2.6.6. Scan the QR Code to Discuss

image0