Python SciPy

확률 분포와 난수 생성 (SciPy.stats)

PyExplorer 2025. 3. 16. 10:33
728x90

확률 분포와 난수 생성 (SciPy.stats)

1. 서론

확률과 통계는 데이터 분석과 머신러닝에서 매우 중요한 역할을 합니다. 특히 확률 분포는 데이터의 특성을 이해하고 예측 모델을 만드는 데 필수적입니다. SciPy의 scipy.stats 모듈은 다양한 확률 분포와 통계 함수를 제공하여 확률 모델을 쉽게 다룰 수 있도록 돕습니다.

이번 포스팅에서는 SciPy를 활용한 확률 분포의 기본 개념과 난수 생성 방법을 자세히 살펴보겠습니다.


2. 확률 분포란?

확률 분포(Probability Distribution)는 특정 확률 변수에 대해 발생할 수 있는 값과 그 값에 대한 확률을 정의하는 수학적 함수입니다. 확률 분포는 이산 분포연속 분포로 나뉩니다.

2.1. 이산 확률 분포

이산 확률 분포는 특정한 정수 값에 대해 확률을 할당하는 분포입니다. 예를 들어, 동전을 던지는 실험에서 앞면과 뒷면이 나올 확률은 각각 50%입니다. 대표적인 이산 확률 분포는 다음과 같습니다.

  • 베르누이 분포 (Bernoulli Distribution): 성공(1)과 실패(0) 중 하나의 결과를 가지는 분포
  • 이항 분포 (Binomial Distribution): 독립된 베르누이 시행을 여러 번 반복했을 때 성공 횟수의 분포
  • 포아송 분포 (Poisson Distribution): 일정 시간 동안 특정 사건이 발생하는 횟수를 표현하는 분포

2.2. 연속 확률 분포

연속 확률 분포는 무한히 많은 값 중 특정 구간에 속할 확률을 나타냅니다. 대표적인 연속 확률 분포는 다음과 같습니다.

  • 정규 분포 (Normal Distribution): 평균과 표준편차로 정의되는 종 모양의 분포
  • 균일 분포 (Uniform Distribution): 특정 구간에서 모든 값이 동일한 확률을 가지는 분포
  • 지수 분포 (Exponential Distribution): 사건이 발생하는 시간 간격을 나타내는 분포

3. SciPy를 활용한 확률 분포 다루기

이제 SciPy의 scipy.stats 모듈을 이용해 대표적인 확률 분포를 생성하고 분석하는 방법을 알아보겠습니다.

3.1. 정규 분포 (Normal Distribution)

정규 분포는 평균과 표준편차를 중심으로 좌우 대칭 형태를 이루는 분포입니다. SciPy에서는 stats.norm을 이용해 정규 분포를 생성하고 분석할 수 있습니다.

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

# 평균과 표준편차 설정
mean = 0
std_dev = 1

# 정규 분포에서 난수 생성
data = norm.rvs(loc=mean, scale=std_dev, size=1000)

# 확률 밀도 함수 (PDF) 시각화
x = np.linspace(-4, 4, 1000)
pdf = norm.pdf(x, loc=mean, scale=std_dev)

plt.figure(figsize=(10, 6))
plt.hist(data, bins=30, density=True, alpha=0.6, color='skyblue', label='Histogram')
plt.plot(x, pdf, 'r', label='PDF')
plt.title('정규 분포와 난수 생성')
plt.xlabel('값')
plt.ylabel('확률 밀도')
plt.legend()
plt.grid()
plt.show()

이 코드에서는 평균 0, 표준편차 1을 가진 정규 분포에서 1000개의 난수를 생성하고, 해당 분포의 확률 밀도 함수와 히스토그램을 시각화했습니다.

3.2. 이항 분포 (Binomial Distribution)

이항 분포는 독립된 베르누이 시행을 여러 번 반복했을 때 성공 횟수의 분포를 나타냅니다.

from scipy.stats import binom

# 이항 분포 설정 (시행 횟수=10, 성공 확률=0.5)
n = 10
p = 0.5
x = np.arange(0, n+1)
pmf = binom.pmf(x, n, p)

plt.figure(figsize=(10, 6))
plt.bar(x, pmf, color='lightcoral', alpha=0.7)
plt.title('이항 분포 PMF')
plt.xlabel('성공 횟수')
plt.ylabel('확률')
plt.grid(axis='y')
plt.show()

이 코드는 10번의 시행에서 성공 확률이 50%일 때 성공 횟수의 확률 분포를 시각화한 것입니다.

3.3. 균일 분포 (Uniform Distribution)

균일 분포는 특정 구간에서 모든 값이 동일한 확률을 가지는 분포입니다.

from scipy.stats import uniform

# 균일 분포 설정 (0에서 10까지)
a, b = 0, 10
x = np.linspace(a, b, 1000)
pdf = uniform.pdf(x, loc=a, scale=b-a)

plt.figure(figsize=(10, 6))
plt.plot(x, pdf, 'g', label='PDF')
plt.fill_between(x, pdf, alpha=0.3)
plt.title('균일 분포')
plt.xlabel('값')
plt.ylabel('확률 밀도')
plt.legend()
plt.grid()
plt.show()

3.4. 포아송 분포 (Poisson Distribution)

포아송 분포는 일정 시간 동안 특정 사건이 발생하는 횟수를 나타냅니다.

from scipy.stats import poisson

# 포아송 분포 설정 (λ=3)
lambda_ = 3
x = np.arange(0, 15)
pmf = poisson.pmf(x, mu=lambda_)

plt.figure(figsize=(10, 6))
plt.bar(x, pmf, color='lightgreen', alpha=0.7)
plt.title('포아송 분포 PMF')
plt.xlabel('사건 발생 횟수')
plt.ylabel('확률')
plt.grid(axis='y')
plt.show()

4. 난수 생성

SciPy는 다양한 확률 분포에서 난수를 생성하는 기능을 제공합니다. rvs() 메서드를 사용하면 간단하게 난수를 생성할 수 있습니다.

# 정규 분포에서 난수 생성
normal_random = norm.rvs(loc=0, scale=1, size=10)
print("정규 분포 난수:", normal_random)

# 이항 분포에서 난수 생성
binom_random = binom.rvs(n=10, p=0.5, size=10)
print("이항 분포 난수:", binom_random)

# 균일 분포에서 난수 생성
uniform_random = uniform.rvs(loc=0, scale=10, size=10)
print("균일 분포 난수:", uniform_random)

5. 결론

이번 포스팅에서는 SciPy의 scipy.stats 모듈을 활용해 다양한 확률 분포를 이해하고 난수를 생성하는 방법을 살펴보았습니다. 확률 분포를 이해하면 데이터의 특성을 분석하고, 예측 모델을 구축하는 데 큰 도움이 됩니다.

728x90