[Python] Gaussian/Multinomial Naive Bayes Classification(가우시안/다항 나이브 베이즈 분류) 실습

2020. 7. 2. 19:12ML in Python/Python

 

 나이브 베이즈 모델은 데이터가 적을 때, 간단한 학습으로도 효율적인 성능을 낼 수 있는 기본적인 머신러닝 모형이다. 

https://todayisbetterthanyesterday.tistory.com/17

 

[Data Analysis 개념] NaiveBayes(나이브 베이즈) 모델 - 조건부 확률 / 베이즈 정리 / Multinomial, Gaussian, Be

 나이브 베이즈 분류 예시) 테니스를 좋아하는 한 사람이 있다고 하자. 만약, 이 사람이 1. 날씨가 좋고 2. 습도가 낮은 날에 테니스를 칠 확률은 얼마나 되는가?  주어진 데이터에 따라 경우가 ��

todayisbetterthanyesterday.tistory.com

 나이브 베이즈의 이론에 대한 설명은 위의 링크를 통해 살펴보면 된다. 이 게시글에서는 나이브 베이즈를 파이썬으로 구현하는 실습 과정을 진행할 것이다. 실습을 진행하는 과정은

1. 데이터, 모듈 불러오기

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

3. Multinomial Naive Bayes (다항분포 나이브 베이즈) 

순으로 진행된다.

1. 데이터, 모듈 불러오기

 실습에 사용될 데이터는 iris데이터로 PCA실습 게시글에서 사용한 것과 같은 데이터이다. 그렇기에 데이터에 대한 분석과정과 그 외 확인과정은 생략하도록 하겠다. 

from sklearn import datasets  #실습에 사용할 데이터 셋, iris data
from sklearn.naive_bayes import GaussianNB # Gaussian Naive Bayes 라이브러리
import pandas as pd
iris = datasets.load_iris()
df_X = pd.DataFrame(iris.data)
df_Y = pd.DataFrame(iris.target)

df_X.head()

df_X.head()

df_Y.head()

 

df_Y.head()

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

 가우시안 나이브 베이즈는 설명변수가 연속형일때 사용하는 방법이다. 적은 데이터로도 효율적인 성능을 낼 수 있다. 

자세한 설명은 위의 링크를 통한 이전 게시물에서 확인할 수 있다.  

gnb = GaussianNB()                             # 가우시안 나이브 베이즈 모델
fitted = gnb.fit(iris.data, iris.target)       # 학습 시작
y_pred - fitted.predict(iris.data)             # 학습 결과를 기존 데이터에 적용

fitted.predict_proba(iris.data)[[1,48,51,100]] # 특정 변수의 결과 뽑기(확률)

fitted.predict_proba(iris.data)[[1,48,51,100]]

 위의 결과는 학습 결과를 확률로 나타낸 것이다. target은 "0","1","2" 3가지 경우가 존재한다. 

1번째 데이터의 경우 "0"범주의 확률이 "1"이고,

48번째 데이터의 경우 "0"범주의 확률이 "1"이고,

51번째 데이터의 경우 "1"범주의 확률이 "0.94"이고,

100번째 데이터의 경우 "2"범주의 확률이 "1"이다.

fitted.predict(iris.data)[[1,48,51,100]]    # 특정 변수의 결과 뽑기(범주)

fitted.predict(iris.data)[[1,48,51,100]]

 이는 확률의 결과가 아니라, 예측한 범주를 직접적으로 출력하는 결과물이다. 

 

이제 성능을 확인하기 위해 Confusion matrix를 통해 확인해보자.

from sklearn.metrics import confusion_matrix

confusion_matrix(iris.target, y_pred)

confusion_matrix(iris.target, y_pred)

 위의 Confusion_matrix를 보면 "0범주"의 경우 모두 옳게 분류했고, "1범주"의 경우 3개의 오답이, "2범주"의 경우 3개의 오답이 발생한 것을 볼 수 있다. 이처럼 나이브 베이즈는 투자대비 효용이 높은 간단한 머신러닝 모델임을 확인할 수 있다.

 또한 나이브베이즈에는 Prior을 직접 설정해줄 수 있는 특징이 있다. 즉, 특정 결과의 출현확률이 더 많다고 가중치를 주는 행위이다. Prior을 직접 설정하여 분류작업을 진행해보자.

# "2범주"에 prior를 높게 줘서, 가중치를 주는 경우

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)

"2범주"에 가중치를 준 경우, Confusion matrix

 위의 경우를 보면, 기존에 prior을 설정 안해주었을 때 보다, 가중치를 높게 준 "2범주"의 정확도가 올랐다. 3개 오답에서 0개 오답으로 해당 범주의 오답 개수가 줄었다. 하지만, 가중치가 낮아진 "1범주"의 경우 오답이 눈에 띄게 늘어나는 결과가 나타난다.

# "1범주"에 prior를 높게 줘서, 가중치를 주는 경우

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)

"1범주"에 가중치를 준 경우, Confusion matrix

위의 경우를 보면, prior을 설정하지 않거나, 다른 범주에 prior을 설정해주었을 때 보다, 가중치를 높게 준 "1범주"의 정확도가 올랐다. 3개 오답에서 0개 오답으로 해당 범주의 오답 개수가 줄었다. 하지만, 가중치가 낮아진 "2범주"의 경우 또한 오답이 눈에 띄게 늘어나는 결과가 나타난다.

 

 이처럼 특정 범주의 분류 정확성을 높일 필요가 있을 때, 가중치를 주는 prior 설정을 통해서 특정 범주의 정확성을 높일 수 있다. 하지만 이는 trade-off의 관계로 다른 범주의 정확성을 희생해야한다.

 

3. Multinomial Naive Bayes (다항분포 나이브 베이즈)

 iris 데이터는 연속형 Featue변수를 갖고 있기 때문에, 다항분포 나이브 베이즈를 실습할 수 없다. 그렇기에 난수를 생성하는 방식을 통해서 Multinomial Naive Bayes모델을 실습하도록 하겠다. 

from sklearn.naive_bayes import MultinomialNB # Multinomial Naive Bayes 라이브러리
import numpy as np                            # 난수생성을 위한 행렬 라이브러리
X = np.random.randint(5,size=(6,100))        # 0부터 4까지 난수 생성, 변수 100개, sample size = 6
y = np.array([1,2,3,4,5,6])

 위의 난수 생성 예시를 보면, 전통적인 방법으로는 fitting을 할 수 없는 데이터이다. 하지만 나이브베이즈는 적은 데이터로 학습을 진행시키는 것이 가능하다.

 

clf.MultinomialNB()
clf.fit(X,y)

clf.fit(X,y) 의 결과

print(clf.predict(X[2:3]))

결과

 위의 결과를 보면, X[2:3]이기에 인덱스 "2"에 온 target(3)을 맞춘 것을 볼 수 있다. 사실 이는 난수생성으로 별 의미가 없지만, 학습이 된다는 것을 보여준다.

clf.predict_proba(X[2:3])

clf.predict_proba(X[2:3])

 위의 결과는 target의 범주 "1"~"6"에 대한 X[2]로 예측한 확률을 보여준다. X[2]은 "범주3"일때 확률이 1로 나타난다. 그결과 3으로 예측을 한 것이고 이는 정답이다.

  마찬가지로, 가우시안 나이브베이즈처럼 다항분포 나이브베이즈 또한 prior설정이 가능하다. 

clf2 = MultinomialNB(class_prior = [0.1,0.5,0.1,0.1,0.1,0.1])
clf2.fit(X,y)

clf2.fit(X,y) 결과

 Multinomial Naive Bayes의 경우 parameter의 이름이 class_prior로 바뀌었다. prior를 줄 때 염두를 하고 사용할 필요가 있다. 이번에는 범주가 "1"~"6"까지 6개가 있기에 prior리스트에 6개 값을 넣었다. "범주 2"에 가중치를 주었으니, "범주2"의 확률이 올라갔을 것을 예측할 수 있다.

clf2.predict_proba(X[2:3])                  # prior 설정 후 확률

clf2.predict_proba(X[2:3]) - prior 설정 후 결과

 위의 결과를 보면 그대로 예측값은 "범주3"의 확률이 1로 가장 높다. 하지만, 자세히 보면 이전 .predict_proba() 결과와 비교해볼때, prior를 높게 줘서 가중치를 부여한 "범주2"의 확률이 5.872e-35에서 2.936e-34로 증가한 것을 확인할 수 있다. 이처럼 prior을 통해 가중치를 부여한 범주는 오답일지라도, 정답이라고 판단하는 확률이 증가하는 것을 확인할 수 있다.