공부정리/Data Science

[Data Science from Scratch] chapter 13. Naive Bayse

sillon 2022. 8. 2. 23:03
728x90
반응형

참고 서적

도서명: Data Science from Scratch
(밑바닥부터 시작하는 데이터 과학)
저자 : Joel Grus
출판 : 프로그래밍 인사이트

Ch 12. Naive Bayse 

 

Naive Bayes

특성들 사이의 독립을 가정하는 베이즈 정리를 적용한 확률 분류기의 일종
Naive(순진하게) likelihood(가능도)를 곱해 계산해 나간다!

 
Gaussian Naive Bayes

    표본 평균과 표본 분산을 가진 정규분포 하에서 베이즈 정리를 사용하는 알고리즘

Multinomial Naive Bayes

   설명 변수가 주형 변수일   다항 분포 데이터에서 베이즈 정리를 사용하는 알고리즘

Bernoulli naive Bayes

   설명 변수가 범주형 변수일 때, 범주가 2개밖에 없는 경우 베이즈 정리를 사용하는   

    알고리즘

 

 

- Gaussian Naive Bayes

  • 표본 평균과 표본 분산을 가진 정규분포 하에서 베이즈 정리를 사용하는 알고리즘
  • 목표 데이터가 각 범주에 속할 확률을 계산하고, 가장 높은 확률을 가지는 범주로 데이터를 분류
  • 모든 독립변수들이 서로 조건부 독립이라고 가정함

- Multinomial Naive Bayes

  • 설명 변수가 범주형 변수일 때  다항 분포 데이터에서 베이즈 정리를 사용하는 알고리즘
  • 주로 텍스트 분류를 하는데 사용함
 

- Bernoulli naive Bayes

  • 설명 변수가 범주형 변수일 때, 범주가 2개밖에 없는 경우
  • Multinomial Naive Bayes에서 범주형 변수가 이진으로 되어있는 형태임

 

Naive Bayes Summery

데이터를 나이브(단순)하게 독립적인 사건으로 가정하고, 이 독립 사건들을 베이즈 이론에 대입시켜 가장 높은 확률의 레이블로 분류를 실행하는 알고리즘
지도학습 환경에서 효율적으로 사용 가능
 

Naive Bayes  Advantages

  • 분류를 위한 학습 데이터 양이 적음
  • 간단하고 빠르며 효율적

Naive Bayes  Disadvantages

  • 모든 확률을 곱하기 때문에 조건부 확률이 너무 작아져서 비교 불가능한 현상이 발생할 수 있음 (Underflow 현상)
  • 기존에 없는 새로운 정보가 입력된다면 해당 단어에 대한 확률이 0이 될 수 있다.
  • 개체 수가 아주 적은 분류 그룹의 확률은 굉장히 높아질 수 있다. (overfitting problem)

 

Naive Bayes  Disadvantages workaround

- Laplace Smoothing

  • 기존에 없는 새로운 정보가 입력될 때 해당 단어에 대한 확률이 0이 되는 것을 방지
  • 각 분자에 1을 더하고, 분모에는 중복을 제거한 모든 데이터의 수를 더함

- Prevents Underflow

  • 모든 확률을 곱하기 때문에 조건부 확률이 너무 작아져서 비교 불가능한 현상이 발생할 수 있음
  • 확률에 로그를 취하여 언더플로우를 방지할 수 있음

 

Naive Bayes From Scratch code review

class NaiveBayes:
    def fit(self, X, y):
        # get number of samples (rows) and features (columns)
        self.n_samples, self.n_features = X.shape
        # get number of uniques classes
        self.n_classes = len(np.unique(y))
        
        # create three zero-matrices to store summary stats & prior
        self.mean = np.zeros((self.n_classes, self.n_features))
        self.variance = np.zeros((self.n_classes, self.n_features))
        self.priors = np.zeros(self.n_classes)
        
        for c in range(self.n_classes):
            # create a subset of data for the specific class 'c'
            X_c = X[y == c]
            
            # calculate statistics and update zero-matrices, rows=classes, cols=features
            self.mean[c, :] = np.mean(X_c, axis=0)
            self.variance[c, :] = np.var(X_c, axis=0)
            self.priors[c] = X_c.shape[0] / self.n_samples

            
    def gaussian_density(self, x, mean, var):
        # implementation of gaussian density function
        const = 1 / np.sqrt(var * 2 * np.pi)
        proba = np.exp(-0.5 * ((x - mean) ** 2 / var))
        return const * proba

    def get_class_probability(self, x):
        # store new posteriors for each class in a single list
        posteriors = list()

        for c in range(self.n_classes):
            # get summary stats & prior
            mean = self.mean[c]
            variance = self.variance[c]
            prior = np.log(self.priors[c])
            
            # calculate new posterior & append to list
            posterior = np.sum(np.log(self.gaussian_density(x, mean, variance)))
            posterior = prior + posterior
            posteriors.append(posterior)
        
        # return the index with the highest class probability
        return np.argmax(posteriors)
    
    def predict(self, X):
        # for each sample x in the dataset X
        y_hat = [self.get_class_probability(x) for x in X]
        return np.array(y_hat)

 

code reference

https://towardsdatascience.com/implementing-naive-bayes-from-scratch-df5572e042ac

 

Implementing Naive Bayes From Scratch

Coding the inner workings with just Python and NumPy

towardsdatascience.com

 

 

728x90
반응형