본문 바로가기

데이터분석/Python

[머신러닝]나이브 베이즈 모델(Naïve bayes clasification) in python

참고) 나이브 베이즈 모델 정의 ,종류, 수식 - [머신러닝]나이브 베이즈(Naïve bayes classifier) 모형

https://topo314.tistory.com/72

 

[머신러닝]나이브 베이즈(Naïve bayes classifier) 모형

1. 나이브 베이즈 모델(Naïve bayes classifier) 1. 특징 2. 정의 2. 나이브 베이즈 모델(Naïve bayes classifier) 종류 1. Gaussian Naïve bayes classifier(가우시안 나이브 베이즈) 2. Multinomial Naïv..

topo314.tistory.com

 

간단한 예제를 통해 가우시안 나이브 베이즈 모델다항 나이브 베이즈 모델을 돌려보겠습니다. 

 

 

 

1. Gaussian Naive Bayes(가우시안 나이브 베이즈)

 

데이터 불러오기

붓꽃의 종류에 관한 데이터인 iris data를 통해 가우시안 나이브 베이즈를 실습하겠습니다. 우선, 필요한 라이브러리들을 불러옵니다. 가우시안 나이브 베이즈는 sklearn.naive_bayes를 통해 불러옵니다.

 

from sklearn import datasets
from sklearn.naive_bayes import GaussianNB
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix #혼동행렬

 

iris 데이터에서 설명변수(독립변수)는 data에, 목표변수(종속변수)는 target에 들어있습니다. head함수를 통해 확인합니다. 설명변수는 연속형, 목표변수는 범주형 변수이고 3가지 붓꽃 종류(0, 1, 2)를 맞추는 3class 문제입니다.

> iris.data[:6, ] #설명변수

array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2],
       [5.4, 3.9, 1.7, 0.4]])
       
> iris.target #목표변수

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

 

 

가우시안 나이브 베이즈 모델 fitting

GaussianNB() 함수를 이용하여 모델을 피팅하고, predict() 함수를 이용하여 iris 데이터의 설명변수에 대한 예측값을 y_pred에 할당합니다.

 

gnb = GaussianNB()
gnb_fit = gnb.fit(iris.data, iris.target)
y_pred = gnb_fit.predict(iris.data)

 

가우시안 나이브 베이즈 모델을 피팅한 gnb_fit에 predict() 함수를 쓰면 목표변수의 예측값(0, 1, 2)을 보여주고, predict_proba() 함수를 쓰면 예측 확률을 보여줍니다. iris 데이터중 5개의 관측값에 대해 예측값과 예측 확률을 확인합니다. 첫번째 관측치(0번째)의 예측값은 0이고 0일 확률은 1, 나머지일 확률은 거의 0에 가까운 것을 확인할 수 있습니다. 101번째 관측치(100번째)의 예측값은 2이고 2일 확률이 99.847%로 매우 높습니다.

 

> gnb_fit.predict(iris.data)[[0, 33, 50, 66, 100]] #예측값
array([0, 0, 1, 1, 2])

> gnb_fit.predict_proba(iris.data)[[0, 33, 50, 66, 99]] #예측확률
array([[1.00000000e+000, 1.35784265e-018, 7.11283512e-026],
       [1.00000000e+000, 3.04886902e-020, 1.36260578e-026],
       [3.21380935e-109, 8.04037666e-001, 1.95962334e-001],
       [1.36110261e-099, 9.90687273e-001, 9.31272734e-003],
       [1.28255689e-074, 9.99847160e-001, 1.52839987e-004]])

 

 

혼동행렬(Confusion matrix) 구하기

iris 데이터의 target(목표변수)와 위에서 만든 가우시안 나이브 베이즈 모델의 예측값을 이용하여 혼동행렬을 계산합니다. 실제로 0인 것을 모두 0으로 잘맞췄고, 실제 1을 2로, 실제 2를 1로 분류한 경우가 각각 3개입니다.

> confusion_matrix(iris.target,y_pred)

array([[50,  0,  0],
       [ 0, 47,  3],
       [ 0,  3, 47]], dtype=int64)

 

 

사전확률(prior prob) 설정하기

priors를 통해 가우시안 나이브 베이즈의 특정 범주의 확률을 바꿀 수 있습니다. 각 범주의 사전 확률을 알고있으면 설정을 통해 더 좋은 결과를 얻을 수 있습니다. 목표변수가 0일 확률을 0.01, 1일 확률을 0.01, 2일 확률을 0.98로 설정하여 똑같이 모형을 적합하고 혼동행렬을 계산했습니다. 마지막 범주(Y=2)가 나올 확률을 높게 한 결과, 이전에서의 결과와 달리 실제 2인 경우 모두 2로 잘 맞추는 대신 실제 1을 2로 잘못 분류하는 경우가 많아졌습니다.

 

gnb2 = GaussianNB(priors=[1/100, 1/100, 98/100])
fitted2 = gnb2.fit(iris.data, iris.target)
y_pred2 = fitted2.predict(iris.data)
confusion_matrix(iris.target, y_pred2)

array([[50,  0,  0],
       [ 0, 33, 17],
       [ 0,  0, 50]], dtype=int64)

 

이번엔 Y가 0, 2일 확률을 각각 0.01, 1일 확률을 0.98로 설정하고 모형을 적합하여 혼동행렬을 계산했습니다. 마찬가지로 Y=1일 확률을 높였더니 실제 1인 경우 모두 잘맞췄지만 실제 2인 경우를 1로 잘못 분류하는 경우가 많아졌습니다.

 

gnb3 = GaussianNB(priors=[1/100, 98/100, 1/100])
fitted3 = gnb3.fit(iris.data, iris.target)
y_pred3 = fitted3.predict(iris.data)
confusion_matrix(iris.target, y_pred3)

array([[50,  0,  0],
       [ 0, 50,  0],
       [ 0, 14, 36]], dtype=int64)

 

 

 

2. Multinomial Naive Bayes(다항 나이브 베이즈, 멀티노미얼 나이브 베이즈)

 

데이터 생성하기

멀티노미얼 나이브 베이즈를 위한 라이브러리를 불러옵니다.

 

from sklearn.naive_bayes import MultinomialNB

 

0부터 4까지 5개의 값을 랜덤으로 가지고 변수가 100개, sample size가 7인 numpy array를 생성합니다. Y는 1부터 7까지 7개의 값을 가집니다.

 

X = np.random.randint(5, size=(7, 100))
y = np.array([1, 2, 3, 4, 5, 6, 7])
X[:2, ]

array([[1, 4, 2, 1, 4, 2, 3, 1, 1, 4, 0, 4, 2, 1, 4, 4, 4, 0, 4, 1, 3, 4,
        3, 1, 4, 4, 2, 4, 0, 0, 4, 1, 2, 0, 1, 3, 0, 2, 1, 4, 3, 4, 4, 4,
        1, 0, 2, 0, 0, 3, 1, 1, 1, 4, 1, 4, 4, 3, 1, 4, 2, 0, 3, 3, 1, 3,
        0, 1, 4, 3, 4, 4, 1, 4, 1, 0, 3, 2, 3, 1, 0, 2, 4, 2, 1, 3, 2, 2,
        4, 0, 4, 3, 2, 1, 1, 4, 1, 3, 1, 0],
       [2, 0, 4, 2, 3, 1, 1, 2, 4, 2, 0, 3, 1, 0, 3, 1, 2, 1, 3, 1, 2, 3,
        4, 2, 1, 2, 1, 0, 4, 2, 0, 4, 4, 1, 2, 2, 0, 0, 3, 2, 3, 0, 0, 0,
        0, 4, 2, 2, 4, 0, 4, 2, 1, 1, 2, 4, 3, 4, 3, 2, 2, 4, 1, 0, 0, 3,
        3, 2, 1, 4, 1, 2, 2, 4, 0, 0, 4, 0, 2, 2, 0, 3, 4, 2, 4, 4, 2, 4,
        0, 1, 4, 4, 2, 2, 4, 4, 1, 1, 3, 3]])

 

 

멀티노미얼 나이브 베이즈 모델 fitting

MultinomialNB() 함수를 이용해 다항 나이브 베이즈 모델을 적합하고 2번째 관측치의 예측값과 예측 확률을 확인합니다. 이 관측치가 두번째 범주(Y=2)은 1이고 나머지 범주가 될 확률은 매우 낮습니다.

 

mnb = MultinomialNB()
mnb.fit(X, y)
mnb.predict(X[1:2])

array([2])

 

mnb.predict_proba(X[1:2])

array([[9.39214796e-32, 1.00000000e+00, 2.12316113e-37, 3.02505576e-43,
        2.56597999e-36, 6.38431972e-34, 4.40755276e-37]])

 

 

사전확률(prior prob) 설정하기

다항 나이브 베이즈에서도 사전확률을 설정할 수 있습니다. 이 확률은 상대적으로 알아서 조정되므로 전체 확률의 합이 1이 아니어도 됩니다. 3번째 범주의 확률을 0.35, 2번째 범주의 확률을 0.15, 나머지 범주의 확률을 각각 0.1로 설정하고 예측확률을 확인합니다. 앞에서 사전확률을 설정하지 않고 돌린 모형과 비교했을 때 , weight를 많이 준 Y=3일 확률이 높아진 것을 확인할 수 있습니다.

 

mnb = MultinomialNB(class_prior=[0.1, 0.15, 0.35, 0.1, 0.1, 0.1, 0.1])
mnb.fit(X, y)
mnb.predict_proba(X[1:2])

array([[6.26143197e-32, 1.00000000e+00, 4.95404263e-37, 2.01670384e-43,
        1.71065332e-36, 4.25621315e-34, 2.93836851e-37]])