✏️ 데이터 사이언스 스쿨에서 공부한 내용입니다.
경찰은 전체 용의자 목록을 가지고 있다. 베이지안 확률론 관점에서 전체 용의자 목록은 바로 표본공간이다. 우리가 알고 싶은 것은 전체 용의자 목록(표본공간)에서 누가 범인(선택된 표본)인가 하는 점이다. 현재 표본공간은 용의자 20명으로 구성되어 있으며 이 중 남자가 12명, 여자가 8명이라고 가정한다.
만약 담당 형사가 범인은 남자라고 생각한다면, ‘범인이 남자이다’라는 주장은 확률론적 관점에서 남성인 용의자(표본)로만 이루어진 사건(표본공간의 부분 집합)이 된다. 이를 사건 라고 하자.
이때 우리가 관심을 가지는 것은 "범인이 남자"라는 사건 의 신뢰도 즉, 사건 의 확률 다. 아무런 추가 정보가 없다면 모든 사람이 범인일 가능성이 같기 때문에 범인이 남자일 확률 는 다음과 같이 전체 용의자 수로 남자 용의자 수를 나눈 값이 된다.
반대로 "범인은 여자"라는 사건은 여집합 로 표현할 수 있고 "범인이 여자일 확률"은 다음처럼 계산한다.
이때 새로운 사건 가 발생했다고 하자. 범인의 것으로 추정되는 긴 머리카락을 발견했다. 이 머리카락에서 범인은 머리카락이 길다는 가능성이 제시되었다.
이 새로운 사건 는 확률론적으로는 새로운 용의자 목록, 즉 머리카락이 긴 사람의 목록이라는 표본공간의 새로운 부분 집합을 의미한다. 그리고 사건 가 발생했다는 것은 이 용의자 목록에 진짜로 범인이 포함되었다는 뜻이다.
현재 표본공간 즉, 전체 용의자 목록에는 머리카락이 긴 사람이 10명, 머리카락이 짧은 사람이 10명이다. 만약 이 사건이 진실이라는 보장이 없다면, 사건 에 대한 확률 , 즉 머리카락이 긴 사람이 범인이라는 주장의 신뢰도는 다음과 같다.
반대로 머리카락이 짧은 사람의 사건은 이고 범인이 머리카락이 짧을 확률은 다음처럼 계산한다.
요약하면 다음과 같다.
베이지안 확률론은 두 사건 와 의 관계를 알고 있다면 사건 가 발생하였했다는 사실로부터 기존에 알고 있는 사건 에 대한 확률 를 좀 더 정확한 확률로 바꿀 수 있는 방법을 알려준다. 이를 위해서는 결합확률과 조건부확률이라는 두 가지 개념을 정의해야 한다.
결합확률(joint probability) 은 사건 와 가 동시에 발생할 확률이다. 즉, 사건(명제/주장) 도 진실이고 사건(명제/주장) 도 진실이므로 사건 와 의 교집합의 확률을 계산하는 것과 같다.
결합확률과 대비되는 개념으로 결합되지 않는 개별 사건의 확률 또는 를 주변확률(marginal probability) 라고 한다.
또한 가 사실일 경우의 사건 에 대한 확률을 사건 에 대한 사건 의 조건부확률(conditional probability) 이라고 하며 다음과 같이 표기한다.
위 수식에서 기호 는 if를 뜻한다. 즉 다음과 같다.
이 조건부확률의 값은 다음처럼 정의한다.
조건부확률이 위와 같이 정의된 근거는 다음과 같다.
사건 가 사실이므로 모든 가능한 표본은 사건 에 포함되어야 한다. 즉, 새로운 실질적 표본공간은 가 된다.
사건 의 원소는 모두 사건 의 원소도 되므로 사실상 사건 의 원소가 된다. 즉, 새로운 실질적 가 된다.
따라서 사건 의 확률 즉, 신뢰도는 원래의 신뢰도(결합확률)를 새로운 표본공간의 신뢰도(확률)로 정규화(normalize)한 값이라고 할 수 있다.
예를 들어 범인 찾기 문제에서는 조건부확률을 다음처럼 정의한다.
조건부확률의 값을 구하기 위해서는 결합확률의 값을 알아야 한다. 그런데 사건 와 사건 의 결합확률의 값 은 기존의 사건 의 확률 나 사건 의 확률 와는 전혀 무관한 별개의 정보이다. 즉, 수학적으로 계산하여 구할 수 있는 값이 아니라 외부에서 주어지지 않으면 안되는 정보인 것이다.
범인 찾기의 경우에도 이미 주어진 정보 , 와 관계없이 는 여러 가지 경우가 있을 수 있다. 예를 들어 어떤 경우에는 12명의 남자 중 머리카락이 긴 사람이 다음과 같이 3명일 수도 있고(경우 1), 6명일 수도 있다(경우 2). 이 두 경우에 대해 조건부확률 를 구해보자.
만약 머리카락이 긴 남자가 3명이라면
이 된다. 원래 사건 의 확률 가 0.6 즉 60% 였으므로 범인이 머리카락이 길다는 정보로 인해 남자가 범인일 확률은 절반으로 뚝 떨어졌다.
만약 머리카락이 긴 남자가 6명이라면
이 된다.
이 경우에는 새로운 정보(사건 )가 주어지든 주어지지 않든 남자가 범인일 확률은 변함없다. 이러한 경우에는 사건 가 사건 와 서로 독립(independent) 이라고 한다.
(경우 1), (경우 2)에 대해 다음 확률을 구하라.
✏️
경우1 | 남자 A | 여자 | 합계 |
---|---|---|---|
길다 B | 3 | 7 | 10 |
짧다 | 9 | 1 | 10 |
합계 | 12 | 8 | 20 |
경우2 | 남자 A | 여자 | 합계 |
---|---|---|---|
길다 B | 6 | 4 | 10 |
짧다 | 6 | 4 | 10 |
합계 | 12 | 8 | 20 |
(1) 범인이 머리카락이 짧다면 범인이 남자일 확률 = 9/10, 6/10
(2) 범인이 머리카락이 길다면 범인이 여자일 확률 = 7/10, 4/10
(3) 범인이 머리카락이 짧다면 범인이 여자일 확률 = 1/10, 4/10
(4) 범인이 남자라면 범인이 머리카락이 길 확률 = 3/12, 6/12
(5) 범인이 여자라면 범인이 머리카락이 길 확률 = 7/8, 4/8
(6) 범인이 남자라면 범인이 머리카락이 짧을 확률 = 9/12, 6/12
(7) 범인이 여자라면 범인이 머리카락이 짧을 확률 = 1/8, 4/8
수학적으로는 사건 와 사건 의 결합확률의 값이 다음과 같은 관계가 성립하면 두 사건 와 는 서로 독립(independent) 이라고 정의한다.
독립인 경우 조건부확률과 원래의 확률이 같아짐을 알 수 있다. 즉, 라는 사건이 발생하든 말든 사건 에는 전혀 영향을 주지 않는 다는 것이다.
다음과 같은 수식도 성립한다.
다음 수식을 증명하라.
(1)
✏️
양변을 으로 나누면 그 자체로 조건부확률을 정의하는 식이다.
(2)
✏️
(1)의 단순한 확장으로서 좌변과 우변은 로 같다.
(3)
✏️
(1), (2)를 응용하면 양변에 를 곱했을 때 좌변과 우변은 로 같다.
가 독립인 사건일 때 다음이 성립함을 증명하라.
✏️
연습 문제 6.5.3 (2) 에서 양변을 로 나누고 B, C가 독립이므로 = 를 적용하면
식 (6.5.20) 이 얻어진다.
조건부확률과 결합확률의 관계를 확장하면 복수의 사건 에 대한 조건부 확률을 다음처럼 쓸 수 있다. 이를 사슬 법칙(chain rule) 이라고 한다.
확률적인 숫자 값을 출력하는 변수를 확률변수(random variable) 라고 한다. 범인 찾기 문제에서는 두 확률변수 , 를 정의할 수 있다. 확률변수 는 성별을 나타내고 확률변수 는 머리카락이 긴지 짧은지를 나타낸다.
두 확률변수 , 가 가질 수 있는 모든 사건의 조합에 대해 독립이 성립하면 두 확률변수 , 가 독립이라고 한다. 위 결합확률 표에서 주변확률의 곱을 구해서 결합확률과 비교해보면 확률변수 , 는 독립이 아니라는 것을 알 수 있다.
경우1 | 남자 X=0 | 여자 X=1 | 합계 |
---|---|---|---|
길다 Y=0 | 3 | 7 | 10 |
짧다 Y=1 | 9 | 1 | 10 |
합계 | 12 | 8 | 20 |
경우2 | 남자 X=0 | 여자 X=1 | 합계 |
---|---|---|---|
길다 Y=0 | 6 | 4 | 10 |
짧다 Y=1 | 6 | 4 | 10 |
합계 | 12 | 8 | 20 |
의 값 | 의 값 | 의 확률 | 의 확률 | 주변확률의 곱 | 결합확률 |
---|---|---|---|---|---|
X=0 | Y=0 | ||||
X=0 | Y=1 | ||||
X=1 | Y=0 | ||||
X=1 | Y=1 |
(경우 2)에 대해 위와 같은 표를 완성하고 확률변수 , 가 독립임을 보여라.
✏️
의 값 | 의 값 | 의 확률 | 의 확률 | 주변확률의 곱 | 결합확률 |
---|---|---|---|---|---|
X=0 | Y=0 | ||||
X=0 | Y=1 | ||||
X=1 | Y=0 | ||||
X=1 | Y=1 |
주변확률의 곱과 결합확률이 같다.
pgmpy(Probabilistic Graphical Models in Python) 패키지를 사용하면 이산확률모형을 쉽게 구현할 수 있다. 피지엠파이 패키지는 다음 명령으로 설치한다.
pip install pgmpy
피지엠파이 패키지의 JointProbabilityDistribution
클래스는 결합확률 모형을 만드는 데 사용하는 클래스다. 사용법은 다음과 같다.
JointProbabilityDistribution(variables, cardinality, values)
variables
: 확률변수의 이름 문자열의 리스트. 정의하려는 확률변수가 하나인 경우에도 리스트로 넣어야 한다.cardinality
: 각 확률변수의 표본 혹은 배타적 사건의 수의 리스트values
: 확률변수의 모든 표본(조합)에 대한 (결합)확률값의 리스트variables
에 들어가는 인수가 사건의 이름이 아니라 확률변수의 이름이라는 점에 주의하라. pgmpy에서는 사건의 이름을 명시적으로 지정할 수 없고 입력한 사건의 수가 일 때, 와 같이 숫자로 지정된다.
범인 찾기 예제에서 성별을 나타내는 확률변수 와 머리카락 길이를 나타내는 확률변수 의 확률을 다음과 같이 표로 정의할 수 있다.
from pgmpy.factors.discrete import JointProbabilityDistribution as JPD
px = JPD(['X'], [2], np.array([12, 8]) / 20)
print(px)
+------+--------+ | X | P(X) | +======+========+ | X(0) | 0.6000 | +------+--------+ | X(1) | 0.4000 | +------+--------+
위의 범인 찾기 문제의 예에서 확률변수 의 확률을 JointProbabilityDistribution
클래스 객체 py
로 구현하라. 확률변수 와 확률변수 의 결합확률은 다음처럼 정의한다.
✏️
from pgmpy.factors.discrete import JointProbabilityDistribution as JPD
import numpy as np
py = JPD(['Y'], [2], np.array([10,10]) / 20)
print(py)
+------+--------+ | Y | P(Y) | +======+========+ | Y(0) | 0.5000 | +------+--------+ | Y(1) | 0.5000 | +------+--------+
확률변수 와 확률변수 의 결합확률은 다음처럼 정의한다.
pxy = JPD(['X', 'Y'], [2, 2], np.array([3, 9, 7, 1]) / 20)
print(pxy)
+------+------+----------+ | X | Y | P(X,Y) | +======+======+==========+ | X(0) | Y(0) | 0.1500 | +------+------+----------+ | X(0) | Y(1) | 0.4500 | +------+------+----------+ | X(1) | Y(0) | 0.3500 | +------+------+----------+ | X(1) | Y(1) | 0.0500 | +------+------+----------+
위의 범인 찾기 문제의 예에서 남자 12명 중 머리카락이 긴 사람이 6명인 경우(경우 2)의 결합확률 모형을 JointProbabilityDistribution
클래스 객체 pxy2
로 구현하라.
✏️
pxy2 = JPD(['X', 'Y'], [2, 2], np.array([6, 6, 4, 4]) / 20)
print(pxy2)
+------+------+----------+ | X | Y | P(X,Y) | +======+======+==========+ | X(0) | Y(0) | 0.3000 | +------+------+----------+ | X(0) | Y(1) | 0.3000 | +------+------+----------+ | X(1) | Y(0) | 0.2000 | +------+------+----------+ | X(1) | Y(1) | 0.2000 | +------+------+----------+
JointProbabilityDistribution
클래스는 결합확률로부터 주변확률을 계산하는 marginal_distribution()
메서드, marginalize()
메서드와 조건부확률을 계산하는 conditional_distribution()
메서드를 제공한다.
marginal_distribution(values, inplace=True)
values
: 주변확률을 구할 확률변수의 이름 문자열 리스트
inplace
: True
이면 객체 자신을 주변확률 모형으로 변화시킨다. False
면 주변확률 모형 객체를 반환한다.
marginalize(values, inplace=True)
values
: 어떤 확률변수의 주변확률을 구하기 위해 없앨 확률변수의 이름 문자열 리스트
inplace
: True
이면 객체 자신을 주변확률 모형으로 변화시킨다. False
면 주변확률 모형 객체를 반환한다.
marginal_distribution()
메서드는 인수로 받은 확률변수에 대한 주변확률분포를 구한다. 다음 코드는 결합확률로부터 주변확률 , 를 계산한다.
pmx = pxy.marginal_distribution(['X'], inplace=False)
print(pmx)
+------+--------+ | X | P(X) | +======+========+ | X(0) | 0.6000 | +------+--------+ | X(1) | 0.4000 | +------+--------+
marginalize()
메서드는 인수로 받은 확률변수를 주변화(marginalize)하여 나머지 확률변수에 대한 주변확률분포를 구한다. 다음 코드도 앞과 마찬가지로 결합확률로부터 주변확률 , 를 계산한다.
pmx = pxy.marginalize(['Y'], inplace=False)
print(pmx)
+------+--------+ | X | P(X) | +======+========+ | X(0) | 0.6000 | +------+--------+ | X(1) | 0.4000 | +------+--------+
다음 코드는 결합확률로부터 주변확률 , 를 계산한다.
py = pxy.marginal_distribution(['Y'], inplace=False)
print(py)
+------+--------+ | Y | P(Y) | +======+========+ | Y(0) | 0.5000 | +------+--------+ | Y(1) | 0.5000 | +------+--------+
conditional_distribution(values, inplace=True)
values
: 조건부확률을 구할 확률변수의 이름 문자열과 값을 묶은 튜플의 리스트
inplace
: True
이면 객체 자신을 조건부확률 모형으로 변화시킨다. False
면 조건부확률 모형 객체를 반환한다.
conditional_distribution()
메서드를 사용하면 어떤 확률변수가 어떤 사건이 되는 조건에 대해 조건부확률값을 계산한다. 다음 코드는 결합확률로부터 조건부확률 , 를 계산한다.
py_on_x0 = pxy.conditional_distribution([('X', 0)], inplace=False) # 사건 A에 대한 조건부확률
print(py_on_x0)
+------+--------+ | Y | P(Y) | +======+========+ | Y(0) | 0.2500 | +------+--------+ | Y(1) | 0.7500 | +------+--------+
다음 코드는 결합확률로부터 조건부확률 , 를 계산한다.
py_on_x1 = pxy.conditional_distribution([('X', 1)], inplace=False)
print(py_on_x1)
+------+--------+ | Y | P(Y) | +======+========+ | Y(0) | 0.8750 | +------+--------+ | Y(1) | 0.1250 | +------+--------+
다음 코드는 결합확률로부터 조건부확률 , 를 계산한다.
px_on_y0 = pxy.conditional_distribution([('Y', 0)], inplace=False) # 사건 B에 대한 조건부확률
print(px_on_y0)
+------+--------+ | X | P(X) | +======+========+ | X(0) | 0.3000 | +------+--------+ | X(1) | 0.7000 | +------+--------+
check_independence()
메서드를 이용하면 두 확률변수 간의 독립도 확인할 수 있다.
pxy.check_independence(['X'], ['Y'])
False
두 개의 JointProbabilityDistribution
객체끼리 곱하면 두 분포가 독립이라는 가정하에 결합확률을 구한다. 이 값과 원래의 결합확률을 비교하면 독립이 아니라는 것을 알 수 있다.
print(px * py)
print(pxy)
+------+------+----------+ | X | Y | P(X,Y) | +======+======+==========+ | X(0) | Y(0) | 0.3000 | +------+------+----------+ | X(0) | Y(1) | 0.3000 | +------+------+----------+ | X(1) | Y(0) | 0.2000 | +------+------+----------+ | X(1) | Y(1) | 0.2000 | +------+------+----------+ +------+------+----------+ | X | Y | P(X,Y) | +======+======+==========+ | X(0) | Y(0) | 0.1500 | +------+------+----------+ | X(0) | Y(1) | 0.4500 | +------+------+----------+ | X(1) | Y(0) | 0.3500 | +------+------+----------+ | X(1) | Y(1) | 0.0500 | +------+------+----------+
위에서 구현한 JointProbabilityDistribution
클래스 객체 pxy2
로부터 주변확률 모형 및 조건부확률 모형을 구하라. 또 check_independence()
메서드를 이용하여 사건 A, B의 독립을 확인하라.
✏️
# 결합확률 모형 (case2)
pxy2 = JPD(['X', 'Y'], [2, 2], np.array([6, 6, 4, 4]) / 20)
print("결합확률 모형 (case2)")
print(pxy2)
# 주변확률 모형
p_m_x = pxy2.marginal_distribution(['X'], inplace=False)
p_m_y = pxy2.marginal_distribution(['Y'], inplace=False)
print("주변확률 모형")
print("확률변수 X")
print(p_m_x)
print("확률변수 Y")
print(p_m_y)
# 조건부 확률 모형
# P(B/A), P(B^C/A)
p_cond_Y_on_X0 = pxy2.conditional_distribution([('X', 0)], inplace=False)
# P(B/A^C), P(B^C/A^C)
p_cond_Y_on_X1 = pxy2.conditional_distribution([('X', 1)], inplace=False)
# P(A/B), P(A^C/B)
p_cond_X_on_Y0 = pxy2.conditional_distribution([('Y', 0)], inplace=False)
# P(A/B^C), P(A^C/B^C)
p_cond_X_on_Y1 = pxy2.conditional_distribution([('Y', 1)], inplace=False)
print("조건부확률 1")
print(p_cond_Y_on_X0)
print("조건부확률 2")
print(p_cond_Y_on_X1)
print("조건부확률 3")
print(p_cond_X_on_Y0)
print("조건부확률 4")
print(p_cond_X_on_Y1)
# 확률변수 간의 독립 확인: 메서드로 확인
print(pxy2.check_independence(['X'], ['Y']))
# 독립의 정의로 직접 확인: 같으면 독립
print(p_m_x * p_m_y)
print(pxy2)
결합확률 모형 (case2) +------+------+----------+ | X | Y | P(X,Y) | +======+======+==========+ | X(0) | Y(0) | 0.3000 | +------+------+----------+ | X(0) | Y(1) | 0.3000 | +------+------+----------+ | X(1) | Y(0) | 0.2000 | +------+------+----------+ | X(1) | Y(1) | 0.2000 | +------+------+----------+ 주변확률 모형 확률변수 X +------+--------+ | X | P(X) | +======+========+ | X(0) | 0.6000 | +------+--------+ | X(1) | 0.4000 | +------+--------+ 확률변수 Y +------+--------+ | Y | P(Y) | +======+========+ | Y(0) | 0.5000 | +------+--------+ | Y(1) | 0.5000 | +------+--------+ 조건부확률 1 +------+--------+ | Y | P(Y) | +======+========+ | Y(0) | 0.5000 | +------+--------+ | Y(1) | 0.5000 | +------+--------+ 조건부확률 2 +------+--------+ | Y | P(Y) | +======+========+ | Y(0) | 0.5000 | +------+--------+ | Y(1) | 0.5000 | +------+--------+ 조건부확률 3 +------+--------+ | X | P(X) | +======+========+ | X(0) | 0.6000 | +------+--------+ | X(1) | 0.4000 | +------+--------+ 조건부확률 4 +------+--------+ | X | P(X) | +======+========+ | X(0) | 0.6000 | +------+--------+ | X(1) | 0.4000 | +------+--------+ True +------+------+----------+ | Y | X | P(Y,X) | +======+======+==========+ | Y(0) | X(0) | 0.3000 | +------+------+----------+ | Y(0) | X(1) | 0.2000 | +------+------+----------+ | Y(1) | X(0) | 0.3000 | +------+------+----------+ | Y(1) | X(1) | 0.2000 | +------+------+----------+ +------+------+----------+ | X | Y | P(X,Y) | +======+======+==========+ | X(0) | Y(0) | 0.3000 | +------+------+----------+ | X(0) | Y(1) | 0.3000 | +------+------+----------+ | X(1) | Y(0) | 0.2000 | +------+------+----------+ | X(1) | Y(1) | 0.2000 | +------+------+----------+