[Python] 확률

0ㅑ채
|2024. 2. 21. 11:17

1.주피터 노트북에서 수학 기호 사용

- TeX 라는 조판 언어를 이용해서 수식을 표현할 수 있음 - Markdown Cell을 생성한 후 셀 안에서 $ 기호를 이용해서 수기을 표현
- 그리스 문자는 \그리스문자이름


2. 공통 코드

import pandas as pd
import numpy as np

#dist 플롯이나 histogram
import seaborn as sns 

#시각화에서 한글을 사용하기 위한 설정
import platform
from matplotlib import font_manager, rc


font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
rc('font', family=font_name)
    
#시각화에서 음수를 표현하기 위한 설정
import matplotlib
matplotlib.rcParams['axes.unicode_minus'] = False 

# Jupyter Notebook의 출력을 소수점 이하 3자리로 제한 
%precision 3

# precision은 소수점은 과학적 표기법으로 변환할 자릿수를 설정
# 아래와 같이 하면 소수점 셋째 자리 밑으로는 과학적 표기법으로 표시
pd.options.display.precision = 3

#경고 무시
import warnings
warnings.filterwarnings('ignore')

 

 

3. 집합

- 구별 가능한 객체의 모임 : 데이터 중복 불가
- 집합은 대문자로 표현, 원소는 소문자로 표현
- Python에서는 set과 frozenset 자료형으로 집합 표현

  • set: 내용 변경 가능한 mutable 자료형
  • frozenset: 내용 변경 불가한 immutable 자료형
    • dict의 key는 반드시 immutable만 가능하기 때문에 frozenset이다. 
    • dir(frozenset): set과 달리 'add' 가 없다. 수정 불가능하니까!

 

3-1) 집합 생성

# set 원소로 생성

a = {1, 2, 3, 1, 2}
print(a)
{1, 2, 3}

 

  • 중복이 자동 제거됨. 

 
# 빈 set 생성

b = {} # dict가 되므로 이렇게 만들면 안됨
print(type(b))

c = set()
print(type(c))
<class 'dict'>
<class 'set'>

 
#frozenset 생성

d = frozenset()
d.add()
AttributeError: 'frozenset' object has no attribute 'add'
  • immutable은 무조건 처음에 데이터를 가지고 만들어야 한다. 수정이 안되니까!
d = frozenset([1, 2, 3])
print(type(d))
<class 'frozenset'>

 
# 연산자 오버로딩
Overloading: 동일한 이름의 메소드가 2개 이상 존재하는 경우 

  • 원래는 함수이지만 연산자를 이용해서 호출할 수 있도록 작성
  • 대신 이 메소드는 매개변수의 개수나 자료형이 달라야 한다.
  • set은 |와 &연산자 가능 (__and__, __or__가 존재)
    원래 이렇게 쓰는 애는 아닌데, 클래스 안에서 재정의해서 다른 용도로 쓰게 하는 것을 연산자 오버로딩이라고 한다.
print({1, 2, 3} & {2, 3, 4})
print({1, 2, 3} | {2, 3, 4})
{2, 3} 
{1, 2, 3, 4}
#부등호도 가능 (__ne__, __lt__가 존재)
print({1, 2, 3} > {2, 3})
  • 부분 집합 여부를 부등호로 판정
True




 
 
 

3-2) 연산

- set에서 합집합, 교집합, 차집합을 구해주는 함수 제공

  • 합집합이나 교집합은 |나 &연산자로도 구할 수 있음

 
 
 

4. 확률

4-1) 확률의 정의와 의미

- 확률은 현실에서 해결하려는 문제와 결부해서 정의
- 어떤 문제가 어떤 답을 가질 수 있고, 답의 신뢰성이 얼마인지 계산하는 정량적 방법 제시

  • ex. 동전을 던졌을 때 앞면이 나올 것인가, 뒷면이 나올 것인가?

 

4-2) 확률에서 나오는 개념

- 확률 표본(random sample, probablistic sample):문제에서 발생할 수 있는 하나의 현상 혹은 선택될 수 있는 하나의 경우(표본)
- 표본 공간: 가능한 모든 표본의 집합   Ω

  • 표본 공간은 도메인 지식을 바탕으로 결정
    • ex. 동전던지기에서 앞면, 뒷면뿐만 아니라 동전이 세워지는 경우도 있다. 그런데 거의 일어나지 않기 때문에 표본 공간은 그냥 앞면, 뒷면만 설정한다.
  • 특별한 경우에는 표본공간의 개수가 무한대가 되기도 한다.
    • ex. 주식의 등락폭: -30% ~ 30%

- 시행: 조작
- 사건(event): 표본 공간의 부분 집합으로 우리가 관심을 가지는 일부 표본의 집합

  • 시행에서 얻을 수 있는 사건의 모든 집합을 전사상이라고 함
    • 동전 던지기에서 나올 수 있는 표본은 앞면과 뒷면
      전사상: {}, {앞면}, {뒷면}, {앞면, 뒷면}

- 확률: 모든 각각의 사건에 어떤 숫자(정량)를 할당하는 함수  P

  • 함수가 지켜야 할 규칙: 콜모고로프의 공리
  • 모든 사건에 대해 확률은 실수이고 0 또는 양수
  • 표본 공간이라는 사건에 대한 확률은 1
  • 공통 원소가 없는 두 사건의 합집합의 확률은 사건별 확률의 합

 

4-3) 확률을 바라보는 관점

- 빈도주의 관점

  • 반복적으로 선택된 표본이 사건 A의 원소가 될 경향을 사건의 확률이라고 본다. 
  • 확률이 0.5 : 10000번 시행했을 때 5000번이 나오는 경향
  • 반복했을 때 몇번 나오니?

 
- 베이지안 관점

  • 신뢰도를 의미한다.
  • 확률이 0.5 : 1번 시행했을 때 그 사건이 발생할 가능성이 50%다.

 
- 보는 각도에 따라 빈도주의 관점이 될 수 있고, 베이지안 관점이 될 수 있다. 

  • 의사가 나에게 병이 걸렸을 가능성이 70%라고 진단을 내렸다.
  • 의사 입장에서는 여러 명의 환자를 진찰하기 때문에 10명이 진료를 받았을 때 7명은 병에 걸린다는 의미. 
  • 환자 입장에서는 내가 병에 걸렸을 가능성이 70%라고 해석하게 된다.

 

4-4) 확률의 성질

- 발생할 수 없는 사건의 확률은 0
- 어떤 사건의 여집합 확률은  1- P
- 합집합은 각 사건의 확률의 합에서 두 사건의 교집합의 확률을 뺀 것
 

4-5) 결합 확률

- 사건 A와 사건 B가 동시에 발생할 확률
- 두 사건의 교집합

 

4-6) 주변 확률

- 개별 사건의 확률: 범인 찾기 문제

  • 전체 인원은 20명에서 남자는 12명, 여자는 8명
  • 남자는 머리가 긴 사람이 3명, 여자는 머리가 긴 사람이 7명일 때, 
  • 범인이 남자이고 머리가 길다면, 결합 확률은 남자이고 머리 긴 사람 3명이므로  3/20
  • 주변 확률: 남자일 확률은 12/30, 머리가 길 확률은 10/20

 

4-7) 조건부 확률

- B가 사실일 경우의 사건 A에 대한 확률이 사건 B에 대한 사건 A의 조건부 확률

- P(B|A): 가능도(likelihood)
- P(B): 정규화 상수(Normalizing Constant) 또는 증거(Evidence)라고 함
 

4-8) 확률을 구해주는 패키지 - pgmpy

- JointProbabilityDistribution(variables, cardinality, values)

  • 결합 확률 모형을 만드는 데 사용하는 클래스
  • variables: 확률 변수의 이름으로 문자열의 리스트로 정의. [문자열이 1개여도 list 사용해야 함!]
  • cardinality: 각 확률 변수의 표본 또는 사건의 개수 [리스트]
  • values: 확률 변수의 모든 표본에 대한 확률 값의 [리스트]

# 남자가 12명이고 여자가 8명일 때 독립 확률

from pgmpy.factors.discrete import JointProbabilityDistribution as JPD

px = JPD(['X'], [2], np.array([12, 8]) / 20) #[12/20, 12/8]
print(px)
  • 남자와 여자는 상호 배타적인 사건이라서 하나의 확률 변수 ['X']
  • 사건의 개수 [2]
+------+--------+
| X    |   P(X) |
+===+=====+
| X(0) | 0.6000 |
+------+--------+
| X(1) | 0.4000 |
+------+--------+

 
# 결합 확률: 확률 변수가 2개 이상인 경우

  • 남자 12명이고 머리가 짧은 사람 9명, 긴 사람 3명
  • 여자 8명이고 머리가 짧은 사람 1명, 긴 사람 7명
    • 남자와 여자는 배타적이지만, 성별과 머리길이는 배타적이지 않으므로 확률 변수가 2개 ( X, Y ) 필요
    • 각 확률변수의 사건의 개수는 긻다,짧다로 2개 
    • 확률 값은 9, 3, 1, 7
pxy = JPD(['X', 'Y'], [2, 2], np.array([3, 9, 7, 1]) / 20)
print(pxy)
  • X: 남자, 여자
  • Y: 머리 짧다, 길다
+------+------+----------+
| 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 |
+------+------+----------+

 
 
- marginal_distribution(values, inplace=True)

  • 주변 확률을 구해주는 함수
  • values: 주변 확률을 구할 확률 변수의 이름 [문자열 리스트]
  • inplace: 기본 값이 Ture
  • JPD 객체를 이용해서 호출

- marginalize(values, inplace=True)

  • values 어떤 확률 변수의 주변 확률을 구하기 위해서 없애줄 확률 변수의 이름 [리스트]

-conditional_distribution(values, inplace=True)

  • values 조건부 확률을 구할 확률 변수의 이름 문자열과 값을 묶은 튜플의 리스트
# x인수로 받은 확률 변수에 대한 주변 확률 분포
pmx = pxy.marginal_distribution(['X'], inplace=False)
print(pmx)

# 인수로 받은 확률 변수를 주변화(marginalize)하여 나머지 확률 변수에 대한 주변 확률 분포
pmx = pxy.marginalize(['Y'], inplace=False)
print(pmx)
+------+--------+
| X    |   P(X) |
+====+====+
| X(0) | 0.6000 |
+------+--------+
| X(1) | 0.4000 |
+------+--------+
+------+--------+
| X    |   P(X) |
+====+=====+
| X(0) | 0.6000 |
+------+--------+
| X(1) | 0.4000 |
+------+--------+

 
 
 

4-9) 베이즈 정리

  • 조건이 주어졌을 때 조건부 확률을 구하는 공식
  • 새로운 데이터가 주어지기 전에 이미 어느정도 확률 값을 알고 있을 때 이를 새로 수집한 데이터와 합쳐서 최종 결과에 반영
  • 데이터 개수가 부족할 때 유용
  • 데이터를 추가하는 상황에서 전체 데이터를 새로 분석할 필요 없이 이전 분석 결과에 새로 들어온 데이터를 합쳐서 업데이트만 수행하면 됨

- 베이즈 정리를 이용한 검사 시욕 문제

  • 병에 걸린 환자에게 시약을 테스트한 결과 99% 확률로 양성반응을 보인 경우, 병에 걸렸는지 알 수 없는 환자에게 시약을 테스트했을 때 양성이 나왔으면 실제 병에 걸렸을 경우는?
    => 환자가 실제로 병에 걸린 경우를 사건 D 라고 하면 병에 걸려있지 않은 경우는 사건 D의 여집합
    => 시약 테스트에서 양성 반응을 보이는 경우를 사건 S 라고 하면 음성 반응을 보이는 경우는 사건 S의 여집합
  • 추가 조사를 했는데 이 병에 걸린 사람은 전체 인구의 0.2%
    => 현재 주어진 확률 값은 병에 걸린 환자에게 시약을 테스트했을 때 양성 반응을 보이는 확률인데 병에 걸렸다는 것은 추가된 조건 혹은 정보이므로 이 확률은 P(S|D) 로 표기
  • 이 병에 걸리지 않은 사람에게 시약 검사를 하면 양성 반응이 나타날 확률 5%
    => 구해야 하는 값은 이것과 반대로 양성 반응을 보이는 환자가 병에 걸려있을 확률인데 이 때에는 양성 반응을 보인다라는 것이 추가된 정보이므로 이 확률은 P(D|S) 로 표기

P(D|S) = P(S|D)P(D) / P(S)

 
- 몬티홀 문제

  • 3개의 문 중에 1개의 문 뒤에 선물이 있고, 나머지 2개의 문에는 선물이 없음
  • 1개의 문을 열어서 선물이 없다는 걸 보여주면 현재 선택한 문을 바꿀 것인가?
  • 실제로 바꾸는 것이 바꾸지 않는 것보다 확률이 2배 높다.

문의 위치를 0, 1, 2로 표현

  • 선물이 있는 문 확률변수 C의 값은 0, 1, 2
  • 참가자가 선택한 문 확률변수 X의 값은 0, 1, 2
  • 진행자가 열어준 문 확률변수 H의 값은 0, 1, 2

참가자가 1번 문을 선택했고, 진행자가 2번 문을 열어 선물이 없음을 보여주면 이진 분류가 된다.

  • 선물은 0번 아니면 1번에 존재
  • 진행자가 어떤 문을 여는가 하는 것은 선물의 위치와 참가자의 선택에 따라 달라지게 된다. 따라서 독립적인 일이 아니라 영향을 받는 일이 된다.
    • 선물이 0번 문 뒤에 있고, 참가자가 1번을 선택하면 진행자는 2번 문을 열 수밖에 없다. 
    • 선물이 1번 문 뒤에 있고, 참가자가 1번을 선택하면 진행자는 0번 아니면 2번 문을 연다. 
  • 0번 문 뒤에 선물이 있을 확률
    (1/3) / ((1 * 1/3) + (1/2 + 1/3) + (0 * 1/3))
    => 2/3
  • 1번 문 뒤에 있을 확률
    (1 - 2/3)
    => 1/3

'Python' 카테고리의 다른 글

[Python] 기술통계  (0) 2024.02.22
[Python] 이미지 데이터 다루기  (0) 2024.02.21
[Python] 데이터 스케일링  (1) 2024.02.16
[Python] 데이터 전처리  (0) 2024.02.15
[Python] 데이터 시각화  (0) 2024.02.14