기본 콘텐츠로 건너뛰기

[matplotlib] 등고선(Contour)

[data analysis] 베이즈정리 (Bayes theorem)

베이즈정리 (Bayes theorem)

관련된 내용

예 1)

표 1은 사무실 lamp을 생산하는 공장 A, B, C의 생산율과 불량품율에 대한 자료입니다.

표 1 공장별 생산에 대한 자료
공장 Product D, P(D|Product)
A 0.35 0.015
B 0.35 0.01
C 0.3 0.02
Product: 생산율, D: 불량률

생산된 불량품이 각 공장에서 생산되었을 확률?

공장 C에서 생산되었을 확률은 식1과 같이 나타낼 수 있습니다.

P(C|D)=P(CD)P(D)(식 1)

표 1에서 공장 C에서의 불량품율에 대한 정보를 사용할 수 있습니다. 즉, P(D|C)은 식 2와 같이 계산할 수 있습니다.

P(D|C)=P(DC)P(C)(식 2)

교집합은 교환법칙이 성립하므로 P(D ∩ C) = P(C ∩ D)로 치환할 수 있습니다(식 3).

P(CD)=P(D|C)P(C)=0.020·0.3=0.006 (식 3)

P(D)는 각 공장에서의 불량품 확률의 합과 같습니다(식 4).

P(D)=P(DA)+P(DB)+P(DC)=P(D|A)P(A)+P(D|B)P(B)+P(D|C)P(C)=0.015·0.35+0.01·0.35+0.02·0.30=0.01475(식 4)
A=np.array([0.35, 0.015])
B=np.array([0.35, 0.01])
C=np.array([0.3, 0.02])
data=pd.DataFrame(np.c_[A, B, C], index=["P(factory)","P(D|factory)"], columns=["A","B","C"]).T
data 
P(factory)P(D|factory)
A 0.35 0.015
B 0.35 0.010
C0.30 0.020
dat=data.values
D_tot=np.sum(np.prod(dat, axis=1))
print(D_tot)
0.01475

위 결과를 적용하면 불량품 D가 공장 C에서 생산되었을 확률 즉, 식 2의 계산결과는 다음과 같습니다.

DC=dat[2,0]*dat[2, 1]/D_tot
round(DC, 3)
0.407

P(D|C)와 같은 방법으로 공장 A, B에서 불량품을 생산할 확률을 계산해 봅니다(식 5).

P(A|D)=P(AD)P(D)=P(D|A)P(A)P(D)P(B|D)=P(BD)P(D)=P(D|BB)P(D)(식 5)
AC=dat[0,0]*dat[0, 1]/D_tot
round(AC, 3)
0.356
BC=dat[1,0]*dat[1, 1]/D_tot
round(BC, 3)
0.237

위 예에서 P(A), P(B), P(C)는 부가적인 정보를 계산하기 전에 얻을 수 있는 확률로서 사전확률 (prior probability)라고 합니다. 이 사전확률들을 기반으로 계산할 수 있는 조건부확률 P(A|D), P(B|D), P(C|D)를 사후확률 (posterior probability)라고 합니다. 즉, 사후확률은 사전확률로부터 불량품률과 같은 부가적인 정보를 획득한 후에 어떤 사건의 조건부 확률을 계산할 수 있는 확률을 의미합니다. 위의 과정을 일반화한 정리를 베이즈정리 (Bayes theorem)이라 합니다.

[베이즈정리 (Bayes theorem)]

표본 공간 S에서 여러 부분공간들(B1, B2, · · · , Bk)이 독립인 경우 식 6과 같이 나타낼 수 있습니다.

S=B1B2Bk (식 6)

표본 공간의 모든 사건이 독립이므로 표본 공간과 연관된 사건 A의 총 발생은 식 7과 같이 A를 조건으로 하는 모든 발생들의 합과 같습니다.

A=(AB1)(AB2)(ABk)P(A)=P(AB1)P(AB2)P(ABk)=i=1kP(ABi)=i=1kP(A|Bi)P(Bi) (식 7)

위의 관계로 부터 Bk의 사후확률은 식 8이 같이 계산됩니다.

P(Bk|A)=P(BkA)P(A)=P(A|Bk)P(Bk)i=1kP(A|Bi)P(Bi) (식 8)

예 2)

공구함에 포함되어 있는 40개의 퓨즈들 중에 5개는 완전한 불량품(D)이고 10개는 1시간 동안 지속되는 부분불량품(pD), 나머지 25개는 정상품(G)입니다. 한 개가 선택되는 경우 완전한 불량품이 아닌 상품을 선택할 확률?

퓨즈를 불량품과 불량(D)이 아닌 제품(ND)로 분류한다면 G는 ND에 포함되어 있습니다. 그러므로 문제의 조건부 확률 P(G|ND)는 식 9와 같이 계산됩니다.

P(GND)=P(G)P(G|ND)=P(GND)P(ND)=P(G)P(ND) (식 9)
PD=5/40
Ppd=10/40
PG=25/40
PND=PG+Ppd
condPG_ND=PG/PND
print(round(condPG_ND, 3))
0.714

예 3)

A에게 두 아이가 있는데 가장 어린 아들과 함께 어떤 모임에 참석해야 합니다. 그가 그 모임에 참석할 수 있다면 그의 가족에 두 아들들만이 포함될 확률?

  • 표본공간 S={(b,b), (b,g), (g, b), (g,g)}, b:boy, g: girl
  • 참석 조건에 부합하는 모든 사건 A={(b,b), (g, b)}
  • 대상이 되는 사건 B={(b,b)}

위 조건을 근거로 P(B|A)는 식 9와 같이 계산됩니다.

P(B|A)=P(BA)P(A)=P(B)P(A)(식 9)
S=4
PA=2/S
PB=1/S
PB_A=PB/PA
PB_A
0.5

예 4)

다음 자료는 일정기간 kospi(kos)와 kodaq(kq)의 종가(Closing price)들에 대한 2일간의 변화에 대한 것으로 증가를 1, 하락을 0으로 목록화 한 것입니다. 두 종목의 가격 변동은 독립일까요?

kospi: [1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1]
kosdaq: [1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1]

이 자료는 파이썬 패키지 FinanceDataReader를 사용하여 호출한 일일 자료를 조정한 것으로 다음 코드를 사용하여 작성한 것입니다.

import FinanceDataReader as fdr
import pandas as pd
st=pd.Timestamp(2023, 2, 20) #(1)
et=pd.Timestamp(2023, 3,20)  
kos=fdr.DataReader('KS11', st, et)['Close'] #(2)
kq=fdr.DataReader('KQ11', st, et)['Close']
kos1=kos.pct_change()
kos1=kos1.replace(0, method='ffill')  #(3)
kos1=kos1.dropna() #(4)
kq1=kq.pct_change() #(5)
kq1=kq1.replace(0, method="ffill")
kq1=kq1.dropna()
kos2=pd.cut(kos1, bins=[-1, 0, 1],labels=[0, 1])  #(6)
kq2=pd.cut(kq1, bins=[-1, 0, 1],labels=[0, 1])
data= pd.concat([kos2, kq2], axis=1)  # (7)
data.index=range(1, len(kos2)+1)
data
Close Closel
1 1 1
2 0 0
3 1 1
16 1 1
17 0 1
18 1 1

위 코드에 사용한 코드는 다음과 같습니다.

코드 번호함수/메소드내용
(1) Timesptamp()날짜 데이터를 생성하는 것으로 수치형을 날짜형으로 변환
(2) DataReader() 호출한 자료는 DataFrame 형식으로 열이름은 'Open','High','Low','Close', 'Volume', 'Change'등을 포함합니다. 이중에 'Close'만을 선택
(3) .replace()특정한 값을 지정한 값으로 변환. 자료 중 0을 앞 행의 값으로 변환
(4) .dropna() 자료 중 결측치 값을 포함한 행을 제거
(5) .pct_change()같은 열의 2개의 행간의 변화율을 계산
(6) .cut()연속변수의 구간을 설정하여 categorical 변수로 전환
(7) .concat()두 DataFrame 객체를 결합

두 집단의 독립여부는 교집합을 고려하여 판단할 수 있습니다. 즉, 독립사건들의 교집합에 대한 확률은 두 확률의 곱으로 계산됩니다. 두 집단이 독립이라면 식 10과 같이 그 두 확률의 곱 결과는 조건부 확률에 의한 결과와 같을 것입니다.

P(kos = 1) ∩ P(kq = 1) = P(kos = 1|kq = 1)P(kq = 1)(식 10)
→ 독립인 경우 P(kos = 1) ∩ P(kq = 1) = P(kos = 1) * P(kq = 1)

위 표에 대한 교차표를 작성해 봅니다. 이는 pd.crosstab() 함수를 사용합니다.

  • pd.crosstab(index, columns, rownames=None, colnames=None, margins=False, margins_name= 'All', dropna= True, normalize=False)
    • 두 개 (또는 그 이상)의 요인(factor)에 대한 교차표를 작성합니다.
    • index, columns : 각각 행과 열에서 그룹화 할 값
    • rownames, colnames: 표의 행과 열의 이름
    • margins=True → 행합과 열합을 마지막 행과 열에 첨부, 그 행과 열의 이름은 margins_name으로 지정할 수 있음
    • dropna=True이면 NA 값은 삭제. 행과 열의 수가 일치하지 않을 경우는 False를 선택 즉, 행과 열의 수가 일치하지 않을 경우 True이면 행 기준의 합과 열의 합 사이에 불일치가 발생
    • 값들의 정규화의 여부를 지정. 이 인수에 전달 할 수 있는 인수값은 다음과 같습니다.
      • normalize=True or all 이면 각 값은 총합으로 나눈 값을 반환
      • normalize=index, 각 행에 대해 정규화
      • normalize=column, 각 열에 대해 정규화
kos= np.array([1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1])
kq= np.array([1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1])
ct=pd.crosstab(kos, kq, rownames=['kospi'], colnames=['kq'], margins=True)
ct
kq 0 1 All
kospi
0 6 2 8
1 2 8 10
All 8 10 18

P(kos = 1) * P(kq = 1)의 결과

round(ct.iloc[1,2]/18*ct.iloc[1,2]/18, 4)
0.3086

P(kos = 1) ∩ P(kq = 1)의 결과

round(ct.iloc[1,1]/18, 4)
0.4444

위 두 결과가 같지 않으므로 독립이 아닙니다.

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. (1)A=PBP1P1AP=B 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. (식 2)BλI=P1APλP1P=P1(APλP)=P1(AλI)P 식 2의 행렬식은 식 3과 같이 정리됩니다. det(BλI)=det(P1(APλP))=det(P1)det((AλI))det(P)=det(P1)det(P)det((AλI))=det(AλI)det(P1)det(P)=det(P1P)=det(I) 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같...

[sympy] Sympy객체의 표현을 위한 함수들

Sympy객체의 표현을 위한 함수들 General simplify(x): 식 x(sympy 객체)를 간단히 정리 합니다. import numpy as np from sympy import * x=symbols("x") a=sin(x)**2+cos(x)**2 a sin2(x)+cos2(x) simplify(a) 1 simplify(b) x3+x2x1x2+2x+1 simplify(b) x - 1 c=gamma(x)/gamma(x-2) c Γ(x)Γ(x2) simplify(c) (x2)(x1) 위의 예들 중 객체 c의 감마함수(gamma(x))는 확률분포 등 여러 부분에서 사용되는 표현식으로 다음과 같이 정의 됩니다. 감마함수는 음이 아닌 정수를 제외한 모든 수에서 정의됩니다. 식 1과 같이 자연수에서 감마함수는 factorial(!), 부동소수(양의 실수)인 경우 적분을 적용하여 계산합니다. (식 1)Γ(n)={(n1)!n:자연수0xn1exdxn:부동소수 x=symbols('x') gamma(x).subs(x,4) 6 factorial 계산은 math.factorial() 함수를 사용할 수 있습니다. import math math.factorial(3) 6 a=gamma(x).subs(x,4.5) a.evalf(3) 11.6 simpilfy() 함수의 알고리즘은 식에서 공통사항을 찾아 정리하...

sympy.solvers로 방정식해 구하기

sympy.solvers로 방정식해 구하기 대수 방정식을 해를 계산하기 위해 다음 함수를 사용합니다. sympy.solvers.solve(f, *symbols, **flags) f=0, 즉 동차방정식에 대해 지정한 변수의 해를 계산 f : 식 또는 함수 symbols: 식의 해를 계산하기 위한 변수, 변수가 하나인 경우는 생략가능(자동으로 인식) flags: 계산 또는 결과의 방식을 지정하기 위한 인수들 dict=True: {x:3, y:1}같이 사전형식, 기본값 = False set=True :{(x,3),(y,1)}같이 집합형식, 기본값 = False ratioal=True : 실수를 유리수로 반환, 기본값 = False positive=True: 해들 중에 양수만을 반환, 기본값 = False 예 x2=1의 해를 결정합니다. solve() 함수에 적용하기 위해서는 다음과 같이 식의 한쪽이 0이 되는 형태인 동차식으로 구성되어야 합니다. x21=0 import numpy as np from sympy import * x = symbols('x') solve(x**2-1, x) [-1, 1] 위 식은 계산 과정은 다음과 같습니다. x21=0(x+1)(x1)=0x=1or1x4=1의 해를 결정합니다. solve() 함수의 인수 set=True를 지정하였으므로 결과는 집합(set)형으로 반환됩니다. eq=x**4-1 solve(eq, set=True) ([x], {(-1,), (-I,), (1,), (I,)}) 위의 경우 I는 복소수입니다.즉 위 결과의 과정은 다음과 같습니다. x41=(x2+1)(x+1)(x1)=0x=±1,±1=±i,±1 실수...