본문 바로가기
머신러닝, 딥러닝/머신러닝

나이브 베이즈 (Naive Bayes)

by 장찐 2022. 5. 15.

📚 나이브 베이즈

✅ 기본 개념 

 베이즈 룰을 사용해서 종속변수의 확률을 계산하는 알고리즘이다.

즉, 새로운 관측치에 대해서, "종속변수가 특정 값을 가질 확률"을 학습데이터에서 베이즈 공식을 이용하여 구한다. 일반적으로 확률이 제일 큰 값을 종속 변수의 값으로 선정한다. 

 

• 일반 머신러닝 알고리즘과는 다르게 학습 과정이 없기 때문에 별도의 비용함수가 존재하지 않는다. 즉, 학습데이터에 라벨이 관측치들로 확률을 한 번 계산하면 예측값을 도출할 수 있다. 

• 최근에는 많이 사용되지 않고 벤치마크로 사용하는 경우가 많다. 

 

 0,1을 분류하는 문제에서 k개의 피쳐가 있을 때, 종속변수=1일 확률을 아래와 같이 나타낼 수 있다. 

 

✅ 계산 과정 

 독립변수가 2개, 종속변수는 1 or 0인 경우에 대해서 나이브 베이즈 알고리즘을 이용한 계산 예시. 베이즈 정리 기본 개념이 있어야 함. 

 

위의 베이즈 정리를 이용하면 Y=1,0 인 경우의 확률을 아래와 같이 계산할 수 있다. 

 나이브 베이즈는 각 종속변수가 될 확률을 리턴한다. 여기서 0,1 중에서 어떤 값이 될 확률이 높은 지가 중요하고 구체적으로 해당 값을 알 필요는 없다. 따라서 위의 두 식에서 분모가 공통 부분이므로 종속변수 확률을 비교할 때 분모 부분은 계산하지 않고, 분자 값만 비교하면 된다.

 

 

 여기에 추가로 나이브 베이즈에서는 각 피쳐들이 서로 독립이라고 가정한다. 그러므로 위의 두 식에서 분자 부분을 아래와 같이 곱셈 형태로 표현할 수 있다.  

 

분모가 동일하기 때문에 곱셈으로 변형된 분자 부분의 확률만 구하면 종속변수 중에서 어떤 것이 될 확률이 큰지를 구할 수 있다. 이 확률을 계산할 때에는 학습 데이터 값들을 이용한다. 

 

 

📌 예시 : 이진분류 

독립변수 : 습도, 바람 여부 / 종속변수 : 골프 플레이 여부 

 humidity=normal / windy=true 인 경우에 골프 플레이 여부는 어떻게 되는가? 

위 질문에 대한 답을 구하기 위해서는 아래 조건부 식의 값을 학습 데이터에서 구해야 한다. 

좌측의 식을 베이즈 룰로 정리해서 표현하면 

 

우측의 식을 베이즈 룰로 정리해서 표현하면 

 

 

좌측 식의 분자는 독립이라고 가정하므로 아래와 같이 표현이 가능하다 

 

이제 주어진 학습데이터에서 각 확률을 구하면 

 

• P(Humidity=normal|Play=Yes) = 6/9

• P(Windy=true|Play=Yes) = 3/9

• P(Play=Yes) = 9/14 

 

우측 식에 대해서도 마찬가지로 확률을 구해서 비교할 수 있다. 

 

 

 

✅ 연속변수인 경우에는? 

나이브베이즈 사용 시 독립변수가 연속형 변수인 경우에는 특정 값이 될 확률이 0이기 때문에, 범주형 변수와 동일한 방식으로 계산할 수가 없다. 따라서 일반적으로 아래와 같이 두 가지 방식을 사용한다. 

 

(1) 범주형 변수로 취급 : 독립변수가 취하는 값을 기준으로 몇 가지 그룹으로 분리 

 

(2) 특정 확률분포를 사용하여 확률 계산

해당 독립변수가 특정한 확률분포를 가진다고 가정하고 pdf를 이용하여 계산한다.

 

연속형 변수인 경우에는 파이썬에서 정규분포를 사용하는 Gaussian NB를 사용한다. 

https://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.GaussianNB.html#sklearn.naive_bayes.GaussianNB

 

 


📚 예제 : 중고차 구매 여부(acceptable) 

https://rstudio-pubs-static.s3.amazonaws.com/118220_5a7997d6b0aa493c878d661968fc1f08.html

UCI ML repositary에서 제공하는 데이터를 사용하였다. 

 

url= 'http://archive.ics.uci.edu/ml/machine-learning-databases/car/car.data'
# 설명: https://rstudio-pubs-static.s3.amazonaws.com/118220_5a7997d6b0aa493c878d661968fc1f08.html
car_df = pd.read_csv(url, names=['buying','maint','doors','persons','lug_boot','safety','class'], sep=",")

데이터를 불러온다 

#나중에 데이터 프레임 만들기 위해서 변수이름 따로 저장 
features = car_df.columns.tolist()
features.remove('class') #종속변수 따로 빼기

#독립변수 : 라벨 인코딩
from sklearn.preprocessing import OrdinalEncoder, LabelEncoder
o_encoder = OrdinalEncoder()
data_encoded = o_encoder.fit_transform(car_df[features])
car_df_encoded = pd.DataFrame(data_encoded, columns=features)
data_encoded

나이브 베이즈는 선형회귀와 달리 독립변수를 더미변수로 만들 필요가 없다. 모델을 학습하는 것이 아니라, 각 변수의 카테고리를 이용해서 확률 계산을 하는 것이 때문에 One hot encoding이 아니라 ordinal encoder를 사용한다. 각 항목별로 숫자값이 부여되는데, 계산과정에서 이것이 숫자의 의미가 아니라 단순히 항목을 나타내는 것이기 때문에 순서는 상관이 없다. 

 

#종속변수 인코딩 : LabelEncoder
l_encoder = LabelEncoder()
target_encoded = l_encoder.fit_transform(car_df['class'])
car_df_encoded['class'] = target_encoded

종속변수의 경우 라벨 인코더를 사용한다. (ordinal encoder를 사용해도 관계없다) 

data_np = car_df_encoded.values

#train/test 분리
X=data_np[:,:-1]
y=data_np[:,-1]

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state=0)

인코딩을 완료한 car_df_encoded는 위와 같은 형태이다. 이 데이터 프레임에 대해서 train/test를 나눈다. 

 

 

from sklearn.naive_bayes import CategoricalNB

model = CategoricalNB()
model.fit(X_train, y_train)
y_predictions = model.predict(X_test)

from sklearn.metrics import accuracy_score, classification_report
accuracy_score(y_test, y_predictions)

print(classification_report(y_test, y_predictions))

학습 데이터에 대해서 확률 계산(=학습)을 진행한다. 

 

 위의 결과를 보면 1로 분류된 경우가 상당히 낮다. 이는 전체 데이터에서 종속변수=1인 데이터 포인트가 상당히 적어서 제대로 계산이 안되고 있음을 의미한다. 

 

 독립변수에 범주형 변수와 연속형 변수가 모두 있는 경우에는 별도로 처리를 해야한다. 가장 간단한 방법은 연속형 변수를 범주형 변수로 변환하는 것이다. 

 또한, 범주형 변수는 Categorical NB, 연속형 변수는 Gaussian NB로 각각 종속변수에 대한 확률을 계산하고 이를 결합해서 최종 결과를 도출할 수도 있다. 

 

 


📚  Reference

 

 

댓글