1. 통계 용어 정리
- 랜덤 실험
랜덤 실험은 가능한 결과가 여러 개 있고 실험 전에 구체적인 결과를 예측할 수 없습니다.
발생 확률을 수치로 표현할 수 있는 실험입니다.
- 동전을 한 번 던지는 경우
- 두 개의 주사위를 동시에 던지는 경우
- 농구 선수가 자유투를 하는 경우
- 길거리 설문조사에서 유권자에게 후보에 대한 의견을 묻는 경우
- 표본 공간 (S)
랜덤 실험에서 발생할 수 있는 모든 가능한 결과의 집합을 표본 공간이라 하며 통상적으로 로 표 기합니다 표본 공간의 예로는 다음이 있습니다
- 동전 던지기의 경우: 앞면, 뒷면
- 두개의 주사위를 던지는 경우: {(1, 1),(1, 2),…,(6, 6)}
- 사건
사건은 표본 공간 S의 부분집합으로 실험 결과 중 특정 조건을 만족하는 결과들의 집합입니다.
주로 대문자 알파벳으로 표현됩니다. - 확률 변수
표본 공간의 원소들에 실수 값을 할당하는 함수입니다.
확률변수는 일반적으로 대문자 X, Y, Z 등으로 표현됩니다.
2. 베이즈 정리
- 베이즈 정리는 어떤 사건이 발생할 확률을 업데이트하는 방법을 알려주는 공식입니다.
- 처음에 알고 있던 확률 (사전 확률) 에 새로운 정보 (증거) 를 반영해서 더 정확한 확률 (사후 확률)을 구하는 데 사용됩니다.
2.1 베이즈 정리 공식
공식은 다음과 같습니다.
$ P(A | B) = \frac{P(B | A) \cdot P(A)}{P(B)} $
하지만 이 수식만 보면 어려울 수 있으니, 쉽게 풀어서 설명해 보겠습니다.
2.2 실생활 예제
🍊 오렌지 상자에서 썩은 오렌지를 찾는 문제
오렌지가 들어있는 두 개의 상자가 있다고 가정해 봅시다.
- 첫 번째 상자에는 100개의 오렌지가 있고, 그중 10개, 10% 가 썩었습니다.
- 두 번째 상자에는 100개의 오렌지가 있고, 그중 20개, 20% 가 썩었습니다.
이제 우리가 무작위로 한 개의 오렌지를 꺼냈는데, 썩어 있었다고 합시다.
그러면 이 오렌지가 첫 번째 상자에서 나왔을 확률은 얼마일까요?
이 문제를 베이즈 정리를 이용해서 해결해 보겠습니다.
2.3 베이즈 정리 적용
우리가 구해야 하는 값은 "썩은 오렌지가 첫 번째 상자에서 나왔을 확률"입니다.
즉, ( P(첫 번째 상자 | 썩은 오렌지) ) 를 구하는 것입니다.
베이즈 정리의 구성 요소를 정리하면 다음과 같습니다.
- 사전 확률 Prior Probability
- 오렌지를 꺼낼 때, 첫 번째 상자를 선택할 확률: 50%
- 즉, ( P(첫 번째 상자) = 0.5 )
- 우도 Likelihood
- 첫 번째 상자에서 오렌지를 꺼냈을 때, 썩어 있을 확률: 10%
- 즉, ( P(썩은 오렌지 | 첫 번째 상자) = 0.1 )
- 전체 확률 Evidence
- 전체에서 썩은 오렌지가 나올 확률을 계산해야 합니다.
- 첫 번째 상자에서 썩은 오렌지가 나올 확률: ( 0.5 \times 0.1 = 0.05 )
- 두 번째 상자에서 썩은 오렌지가 나올 확률: ( 0.5 \times 0.2 = 0.1 )
- 전체적으로 썩은 오렌지가 나올 확률: ( 0.05 + 0.1 = 0.15 )
이제 베이즈 정리를 적용합니다.
$$
P(\text{첫 번째 상자} | \text{썩은 오렌지}) = \frac{0.1 \times 0.5}{0.15} = \frac{0.05}{0.15} = 0.3333
$$
즉, 썩은 오렌지를 발견했을 때, 그것이 첫 번째 상자에서 나왔을 확률은 33.33% 입니다.
2.4 핵심 정리
베이즈 정리는 다음과 같은 원리를 따릅니다.
- 처음에 알고 있는 확률, 사전 확률: "이게 일어날 가능성이 얼마나 될까?"
- 새로운 정보, 증거: "새로운 단서가 추가되었을 때, 이 확률이 어떻게 변할까?"
- 업데이트된 확률, 사후 확률: "새로운 정보를 반영했을 때, 더 정확한 확률은 얼마일까?"
2.5 예제 문제 1
한 소프트웨어 회사에서 각 버전의 소프트웨어에
대해 버그 발생 비율을 조사한 결과는 다음과 같습니다.
버전 | 비율 | 버그 발생 확률 |
---|---|---|
2022 | 0.16 | 0.05 |
2021 | 0.18 | 0.02 |
2020 | 0.20 | 0.03 |
기타 | 0.46 | 0.04 |
소프트웨어 버전이 2022, 2021, 2020인 소프트웨어 중 하나에서 버그가 발생했다고 합니다.
이 소프트웨어가 2022 버전일 확률을 계산하십시오. 소수점 셋째 자리에서 반올림하세요.
p_2022 = 0.16 * 0.05
p_2021 = 0.18 * 0.02
p_2020 = 0.20 * 0.03
p_bug = p_2022 + p_2021 + p_2020
p_2022_bug = p_2022 / p_bug
# 소수점 셋째 자리에서 반올림
round(p_2022_bug, 2)
2.6 예제 문제 2
한 회사에서 무작위로 선택된 직원이 건강 문제가 있을 확률은 0.25입니다.
건강 문제가 있는 직원은 건강 문제가 없는 직원보다 흡연자일 확률이 두 배 높습니다.
직원이 흡연자라는 사실을 알았을 때, 그가 건강 문제를 가지고 있을 확률을 계산하십시오.
# x에 어떤 숫자를 넣어도 상관 없다.
x = 3333
p_smoke_problem = 1/4 * x * 2
p_smoke_normal = 3/4 * x
p_smoke = p_smoke_normal + p_smoke_problem
ans = p_smoke_problem / p_smoke
확률 변수와 확률 분포 실습
1. 베르누이 분포
1.1 베르누이 분포 개념
- 베르누이 분포는 실행 결과가
0
또는1
두 가지 값만을 가지는 확률 분포입니다. - 예시: 동전 던지기
1.2 베르누이 분포 함수 구현
bernoulli()
함수 구현- 10,000,000번 실행하여 확률 확인
def bernoulli():
rng = np.random.default_rng()
return int(rng.uniform(0, 1) <= 0.5)
rng = np.random.default_rng()
을 통해 0 이상 1 미만의 균등 분포(Uniform Distribution)를 따르는 난수를 생성<= 0.5
조건문 실행을 통해 50%의 확률로 True 를 반환하거나 False 를 반환합니다.int()
를 사용하여 True 는 1로, False 는 0 으로 반환합니다.- 함수를 여러번 실행하면 1 또는 0 이 무작위로 return 됩니다.
cnt = 0
for i in range(10_000_000):
cnt += bernoulli()
print(cnt / 10_000_000) # 0.5001187
- 10, 000, 000회 실행한 결과
- 약 50% 의 확률로 1이 나온다는 것을 알 수 있다.
2. 확률 변수 이해하기
2.1 확률 변수 개념
확률 변수는 확률적으로 결정되는 값 을 의미합니다.
예를 들어, 동전을 던졌을 때, 주사위를 굴렸을 때, 시험 점수 등이 확률 변수입니다.
확률 변수에는 각 값이 나올 확률이 존재하며, 이를 확률 분포 라고 합니다.
예시
- 확률 변수 X가 가질 수 있는 값:
0, 1, 2
- 각 값에 대한 확률:
[0.2, 0.5, 0.3]
p = [0.2, 0.5, 0.3]
def event_x():
rng = np.random.default_rng()
u = rng.uniform(0, 1)
if u <= 0.2: # 0% ~ 20%
return 0
elif u <= 0.7: # 20% ~ 70%
return 1
else:
return 2
event_x()
2.2 확률 변수 생성 최적화
X(size)
: numpy 벡터 연산 활용for_X(size)
: for loop를 활용한 확률 변수 생성
- numpy 를 활용한 연산
# 확률 변수 X가 가질 수 있는 값
choice = np.array([0, 1, 2])
def X(size):
rng = np.random.default_rng()
u = rng.uniform(0, 1, size)
condition = np.array([u <= 0.2, u <= 0.7, u < 1])
return np.select(condition, choice)
np.select()
를 사용하여 조건에 맞는 값을 효율적으로 선택
- for loop를 활용한 연산
def for_X(size):
rng = np.random.default_rng()
u = rng.uniform(0, 1, size)
for i in range(size):
if u[i] <= 0.2:
u[i] = 0
elif u[i] <= 0.7:
u[i] = 1
else:
u[i] = 2
return u
- for 문을 통해 반복문 실행
2.3 연산 속도 비교
import time
을 통해 numpy
연산과 for loop
연산의 속도를 비교
# numpy 연산속도
start = time.time()
X(10_000_000)
end = time.time()
numpy_speed = end - start
# for loop 연산 속도
start = time.time()
for_X(10_000_000)
end = time.time()
for_loop_speed = end - start
# 연산 속도 차이 비교
print(f'numpy: {round(numpy_speed, 2)}, for_loop: {round(for_loop_speed, 2)}')
# numpy: 0.18, for_loop: 2.1
- 결과 값을 보면 표본이 10,000,000개 일 때 약 10배정도의 속도 차이가 발생한다.
3. 확률 변수의 확률 질량 함수
- X는 0, 1, 2 중 하나의 값을 가질 수 있음
P(X=0) = 0.2
20%P(X=1) = 0.5
50%P(X=2) = 0.3
30%
x = np.array([0, 1, 2])
p_x = np.array([0.2, 0.5, 0.3])
3.1 확률 질량 함수 시각화
- 확률 변수 X의 확률 질량 함수를 bar 그래프로 표현
x = np.array([0, 1, 2])
p_x = np.array([0.2, 0.5, 0.3])
plt.bar(x, p_x)
plt.xlabel('Random Variable X')
plt.ylabel('Probability')
plt.title('Probability of X')
plt.xticks(x)
plt.show()
x가 0일 확률은 0.2
x가 1일 확률은 0.5
x가 2일 확률은 0.3 임을 쉽게 확인할 수 있다.
3.2 확률 변수의 기대값
- 확률 변수 X의 기대값(모평균) 계산
- 표본 데이터를 생성하고, 표본 평균을 통해 모평균을 추정
x = np.array([0, 1, 2])
p_x = np.array([0.2, 0.5, 0.3])
# 모평균 E(X)
μ = np.sum(x * p_x)
# 표본 데이터 생성
data = X(200)
# 표본평균
x̄ = data.mean()
모평균 계산하는 법
$ 0 \times 0.2 + 1 \times 0.5 + 2 \times 0.3 $
- x 를 각각 대응되는 확률과 곱해준 뒤 모두 더해준다.
- numpy 를 사용하면 간단하게 구할 수 있다.
3.3 확률 분포 시각화
- 모평균: 빨간 점선 과 실제 표본 데이터 비교
- 200개의 표본을 그래프화 한 뒤에 실제 모평균 값을 시각화
4. 평균이 같고 분산이 다른 확률 변수 비교
- 확률 변수 X의 값:
[0, 1, 2]
- 확률 변수 Y의 값:
[-1, 1, 3]
- 확률 :
[0.2, 0.6, 0.2]
- 두 그래프는 평균이 같지만 각각 분산이 다른 것을 알 수 있다.
- 평균은 데이터를 대표하는 대표값 중 하나이지만 분산에 따라 해석이 달라져야 함을 이해할 수 있다.
y = np.array([-1, 1, 3])
p_y = np.array([0.2, 0.6, 0.2])
e_Y = np.sum(y * p_y)
var_Y = np.sum(p_y * (y - e_Y) ** 2) # 분산 계산
std_Y = np.sqrt(var_Y) # 표준편차 계산
x = np.array([0, 1, 2])
p_x = np.array([0.2, 0.6, 0.2])
e_X = np.sum(x * p_x)
var_X = np.sum(p_x * (x - e_X) ** 2) # 분산 계산
std_X = np.sqrt(var_X) # 표준편차 계산
- 각각의 확률변수 X와 Y의 평균, 분산, 표준편차를 계산하는 코드이다.
5. 확률 변수 X의 확률 분포 문제
- 확률 변수 X가 가질 수 있는 값:
[1, 2, 3, 4]
- 각 값의 확률:
[0.1, 0.3, 0.2, 0.4]
1. X의 평균 계산
e_x = np.sum(x * p_x)
- x 를 각각 대응되는 확률과 곱해준 뒤 모두 더해준다.
- numpy 를 사용하면 간단하게 구할 수 있다.
2. X의 분산 계산
var_x = np.sum(((x - e_x)**2) * p_x)
- x 와 모평균의 차이를 구한 뒤 제곱해준다.
- 위에서 구한 값에 확률을 곱해준다.
- 위에서 구한 값을 모두 더해준다.
3. X에서 평균보다 큰 값이 나올 확률 계산
p_bigger = np.sum(p_x[x > e_x])
- 평균보다 큰 값을 필터링한다.
- 필터링 한 결과값으로 확률 array 에 똑같이 필터링 한다.
- 필터링 해서 나온 값을 전부 더해준다.
4. 무작위로 5개의 표본을 추출하여 평균 계산
def X(size):
rng = np.random.default_rng()
u = rng.uniform(0, 1, size)
condition = np.array([u <= 0.1, u <= 0.4, u <= 0.6, u < 1])
return np.select(condition, x)
X(5).mean()
- 랜덤으로 난수를 생성한다 (0~1)
- 조건에 따라 필터링을 해준다.
- 0.1 보다 작거나 같을 경우는 1 (0% ~ 10%)
- 0.4 보다 작거나 같을 경우는 2 (10% ~ 40%)
- 0.6 보다 작거나 같을 경우는 3 (40% ~ 60%)
- 1보다 작을 경우는 4 (60% ~ 100%)
- 필터링 한 결과값을 return 하고, 표본의 평균을 구해준다.
5. 확률 분포 그래프에 모평균: 빨간 선 과 표본 평균: 파란 선 추가
plt.bar(x, p_x)
plt.xlabel('Random Variable X')
plt.ylabel('Probability')
plt.xticks(x)
plt.title('Probability of X')
plt.axvline(e_x, label="μ", color="red")
plt.axvline(X(5).mean(), label="5 size mean", color="blue")
plt.axvline(X(20).mean(), label="20 size mean", color="green")
plt.legend()
plt.show()
- 빨간선은 모평균 값이고,
- 파란선은 표본의 개수가 5개일 때의 평균값이다.
- 초록선은 표본의 개수가 20개일 때의 평균값이다.
- 표본의 개수가 커질수록 모평균에 가까워진다.
- 표본의 개수가 적을수록 변동폭이 크다는 사실을 확인할 수 있다.
확률 변수의 합과 확률 분포 구하기
1. 문제 소개
두 개의 동전을 던지는 실험을 진행하겠습니다.
각 동전은 앞면: 1 또는 뒷면: 0 이 나올 수 있으며, 앞면이 나올 확률은 30% 입니다.
이때, 두 개의 동전을 동시에 던졌을 때 앞면의 개수 Y 에 대한 확률을 계산해 보겠습니다.
즉, Y = 첫 번째 동전 결과 + 두 번째 동전 결과 입니다.
2. 확률 변수 X_1, X_2 정의
각 동전의 결과를 확률 변수 X_1 과 X_2 로 정의합니다.
동전 결과 | 값 | 확률 |
---|---|---|
뒷면: 0 | 0 | 0.7 70% |
앞면: 1 | 1 | 0.3 30% |
이제 두 개의 동전을 동시에 던졌을 때, $ Y = X_1 + X_2 $ 가 될 확률을 계산해 보겠습니다.
3. Y 의 가능한 값과 확률 계산
우리는 두 개의 동전을 던지므로 Y 의 값은 0, 1, 2 중 하나입니다.
가능한 경우를 모두 살펴보겠습니다.
첫 번째 동전 X_1 | 두 번째 동전 X_2 | ( Y = X_1 + X_2 ) | 확률 계산 |
---|---|---|---|
0 | 0 | 0 | ( 0.7 \times 0.7 = 0.49 ) |
0 | 1 | 1 | ( 0.7 \times 0.3 = 0.21 ) |
1 | 0 | 1 | ( 0.3 \times 0.7 = 0.21 ) |
1 | 1 | 2 | ( 0.3 \times 0.3 = 0.09 ) |
결과를 정리하면:
Y 값 | 확률 P(Y) |
---|---|
0 | 0.49 |
1 | 0.21 + 0.21 = 0.42 |
2 | 0.09 |
해석:
- 동전 두 개를 던졌을 때, 두 개 모두 뒷면이 나올 확률은 49%
- 하나만 앞면이 나올 확률은 42%
- 두 개 모두 앞면이 나올 확률은 9%
4. 평균기대값과 분산 계산
확률 변수의 기대값/평균 은 다음과 같이 계산합니다.
$$
E(Y) = E(X_1) + E(X_2)
$$
e_x = 0 * 0.7 + 1 * 0.3 # X의 평균
e_y = e_x + e_x # Y의 평균
print(f"E(Y) = {e_y}") # 0.6
5. 확률 변수의 합 확장하기
만약 7개의 동전을 동시에 던진다면 어떻게 될까요?
$ Y = X_1 + X_2 + X_3 + X_4 + X_5 + X_6 + X_7 $ 일때, 각 YI값의 확률을 구해보겠습니다.
import numpy as np
from itertools import product
# X1 ~ X7의 가능한 값 (0 또는 1)
x_values = [0, 1]
p_x = [0.7, 0.3] # 확률: 0이 나올 확률 0.7, 1이 나올 확률 0.3
# 모든 가능한 조합 생성
combinations = list(product(x_values, repeat=7))
# Y 값과 그에 해당하는 확률 계산
y_probabilities = np.zeros(8) # Y는 0부터 7까지의 값을 가질 수 있음
for combination in combinations:
y_value = sum(combination)
prob = np.prod([p_x[val] for val in combination])
y_probabilities[y_value] += prob
# 결과 출력
for y_value, prob in enumerate(y_probabilities):
print(f"P(Y={y_value}) = {prob:.4f}")
출력 예시
P(Y=0) = 0.0478
P(Y=1) = 0.1722
P(Y=2) = 0.3177
P(Y=3) = 0.3025
P(Y=4) = 0.1361
P(Y=5) = 0.0224
P(Y=6) = 0.0016
P(Y=7) = 0.0001
2025.03.25 - [Data] - LS 빅데이터 스쿨 / 이항 분포 / python
LS 빅데이터 스쿨 / 이항 분포 / python
오늘은 문제 풀이를 통해 이항 분포에 대해 접했습니다.처음 접한 개념이라 생소했지만, 실제 문제를 통해 이해하니 보다 쉽게 이해할 수 있었습니다.이항분포에 대해 알아보고 이를 파이썬 코
kiminchae.tistory.com
'Data > 통계' 카테고리의 다른 글
카이제곱(Chi-Square) 검정 / 범주형 데이터 분석 / 독립성 검정 / 동질성 검정 / 적합도 검정 (1) | 2025.04.07 |
---|---|
정규성 검정 / Shapiro-Wilk / Anderson-Darling / Kolmogorov–Smirnov / Q-Q Plot (0) | 2025.04.04 |
정규분포와 t분포 / Python (1) | 2025.04.03 |
확률질량함수(PMF), 확률밀도함수(PDF), 누적분포함수(CDF) (0) | 2025.03.27 |
이항 분포 예제로 이해하기 with python (0) | 2025.03.25 |