메타 클래스를 활용한 이산 확률 분포 클래스는 연속 확률 분포에서와 마찬가지로 확률 분포 클래스에 공통적인 기능을 동적으로 추가하거나, 클래스를 정의할 때 특정 조건을 검증하는 방법으로 사용할 수 있습니다. 이산 확률 분포에서는 확률 질량 함수(PMF, Probability Mass Function)누적 분포 함수(CDF, Cumulative Distribution Function)가 주로 사용됩니다.

이 예제에서는 이산 확률 분포 클래스에 대해 메타 클래스를 활용하여 다음과 같은 작업을 수행합니다:

  1. 분포 클래스 생성 제약: 이산 확률 분포 클래스에 반드시 pmf (확률 질량 함수)와 cdf (누적 분포 함수)를 구현하도록 강제합니다.
  2. 공통 기능 추가: 이산 확률 분포 클래스들에 공통적인 기능을 자동으로 추가합니다.

예제: 메타 클래스를 활용한 이산 확률 분포 클래스

1. 메타 클래스 정의

먼저, 모든 이산 확률 분포가 pmfcdf 메서드를 반드시 구현하도록 강제하는 메타 클래스를 정의합니다.

# 메타 클래스 정의
class DiscreteDistributionMeta(type):
    def __init__(cls, name, bases, dct):
        super().__init__(name, bases, dct)

        # 이산 확률 분포 클래스는 pmf와 cdf 메서드를 반드시 구현해야 함
        if not all(hasattr(cls, method) for method in ['pmf', 'cdf']):
            raise TypeError(f"{name} 클래스는 'pmf'와 'cdf' 메서드를 반드시 포함해야 합니다.")

2. 기본 이산 확률 분포 클래스 정의

모든 이산 확률 분포 클래스는 pmfcdf 메서드를 구현해야 하며, 이를 구현하지 않으면 NotImplementedError가 발생합니다.

# 이산 확률 분포의 기본 클래스
class DiscreteProbabilityDistribution(metaclass=DiscreteDistributionMeta):
    def pmf(self, x):
        """확률 질량 함수 (PMF)를 반환합니다."""
        raise NotImplementedError("pmf() 메서드가 구현되어 있지 않습니다.")

    def cdf(self, x):
        """누적 분포 함수 (CDF)를 반환합니다."""
        raise NotImplementedError("cdf() 메서드가 구현되어 있지 않습니다.")

3. 구체적인 이산 확률 분포 클래스 구현

이제 메타 클래스와 기본 클래스를 바탕으로 베르누이 분포이항 분포와 같은 구체적인 이산 확률 분포 클래스를 정의합니다.

  • 베르누이 분포: 두 가지 결과(성공/실패)를 가지는 확률 분포.
  • 이항 분포: 여러 번의 베르누이 시행에서 성공 횟수를 따르는 확률 분포.
1) 베르누이 분포 (Bernoulli Distribution) 클래스
import numpy as np

class BernoulliDistribution(DiscreteProbabilityDistribution):
    def __init__(self, p):
        """
        p: 성공 확률 (0 <= p <= 1)
        """
        self.p = p

    def pmf(self, x):
        """베르누이 분포의 PMF: P(X=x) = p^x * (1-p)^(1-x)"""
        if x not in [0, 1]:
            return 0  # 이산 확률 분포에서 0과 1 이외의 값은 0의 확률을 가짐
        return self.p if x == 1 else 1 - self.p

    def cdf(self, x):
        """베르누이 분포의 CDF"""
        if x < 0:
            return 0
        elif x < 1:
            return 1 - self.p
        else:
            return 1

# 베르누이 분포 예제
bern_dist = BernoulliDistribution(p=0.6)
print(f"Bernoulli PMF at x=1: {bern_dist.pmf(1)}")
print(f"Bernoulli PMF at x=0: {bern_dist.pmf(0)}")
print(f"Bernoulli CDF at x=1: {bern_dist.cdf(1)}")
2) 이항 분포 (Binomial Distribution) 클래스
class BinomialDistribution(DiscreteProbabilityDistribution):
    def __init__(self, n, p):
        """
        n: 시행 횟수
        p: 성공 확률
        """
        self.n = n
        self.p = p

    def pmf(self, k):
        """이항 분포의 PMF: P(X=k) = nCk * p^k * (1-p)^(n-k)"""
        from scipy.special import comb
        if k < 0 or k > self.n:
            return 0
        return comb(self.n, k) * (self.p ** k) * ((1 - self.p) ** (self.n - k))

    def cdf(self, k):
        """이항 분포의 CDF"""
        cdf_value = 0
        for i in range(0, k + 1):
            cdf_value += self.pmf(i)
        return cdf_value

# 이항 분포 예제
binom_dist = BinomialDistribution(n=5, p=0.5)
print(f"Binomial PMF at k=3: {binom_dist.pmf(3)}")
print(f"Binomial CDF at k=3: {binom_dist.cdf(3)}")

4. 오류가 발생하는 경우

만약 pmfcdf 메서드를 구현하지 않고 클래스를 정의하려고 하면, 메타 클래스가 정의된 대로 TypeError가 발생합니다.

# 잘못된 분포 클래스 예시 (pmf와 cdf 미구현)
class InvalidDistribution(DiscreteProbabilityDistribution):
    pass

# 이 코드는 TypeError를 발생시킴
# InvalidDistribution 클래스는 pmf, cdf 메서드가 없으므로 오류 발생

설명

  1. DiscreteDistributionMeta 메타 클래스:

    • 이 메타 클래스는 클래스가 정의될 때 pmfcdf 메서드를 가지고 있는지 확인합니다.
    • 이산 확률 분포에서 pmf(확률 질량 함수)와 cdf(누적 분포 함수)를 반드시 정의해야 한다는 제약을 적용합니다.
  2. DiscreteProbabilityDistribution 클래스:

    • 이산 확률 분포의 기본 클래스로, 이 클래스를 상속받는 모든 분포는 pmfcdf 메서드를 구현해야 합니다.
    • 기본 클래스에서 이 두 메서드를 정의하지 않으면 NotImplementedError를 발생시켜, 추상 클래스 역할을 합니다.
  3. 구체적인 이산 분포 클래스 (베르누이 분포, 이항 분포):

    • BernoulliDistribution 클래스는 베르누이 분포를 구현하고, pmfcdf 메서드를 제공합니다.
    • BinomialDistribution 클래스는 이항 분포를 구현하고, 이 역시 pmfcdf 메서드를 제공합니다.
  4. 클래스 생성 시 제약:

    • pmfcdf를 구현하지 않은 이산 분포 클래스를 만들면 TypeError가 발생하여 클래스를 정의할 수 없습니다.

실행 결과

Bernoulli PMF at x=1: 0.6
Bernoulli PMF at x=0: 0.4
Bernoulli CDF at x=1: 1
Binomial PMF at k=3: 0.3125
Binomial CDF at k=3: 0.8125
TypeError: InvalidDistribution 클래스는 'pmf''cdf' 메서드를 반드시 포함해야 합니다.

요약

이 예제에서는 메타 클래스를 활용하여 이산 확률 분포 클래스를 정의할 때, pmfcdf 메서드를 반드시 구현하도록 강제했습니다. 이를 통해 확률 분포 클래스 설계에서 일관성을 유지하고, 확률 분포 클래스에 공통된 기능을 적용할 수 있습니다.

+ Recent posts