여태까지
hmm lm 을 중점적으로 봤음
어떤 prediction -> 이전까지의 prediction 을 고려해서 계산
naive bayes는 이전 prediction 고려하지 않고 독립적으로 계산
베이즈 룰을 따르는 모델
document 안에 있는 Feature들을 사용해서 어떤 classify model 을 만들거다...
대표적으로 bag of word feature를 사용함..
아웃풋이 바이너리냐가 기준이 아님!
예를 들어서,
몸무게 같은 실수형 feature로 과체중/아님을 분류하면 Gaussian NB 사용
텍스트를 단어 등장 여부(0/1)로 표현하면 Bernoulli NB
단어 등장 횟수(counts)라면 Multinomial NB
왜 나이브?
이전까지 봤던 건 interdepenent했음
어던 document 가 어떤 class 에 속하지? 를 계산
p(c|d) 를 구하기 어렵기 때문에
베이즈룰을 적용해서
posterial prob = likelihood * prior prob ??
document가 주어졌을 때, 어떤 클래스 c에 속할 확률이 높은지를 따짐.
이 document 가 a에 속할 확률, b 에 속할 확률... 을 모두 구해서 이 값을 max로 만드는 arg 를 찾는 것...
결국엔 아래 식을 통해 가장 확률 높은 클래스를 선택함.
c' = argmax_c P(c) * P(d | c)
Naive Bayes는 베이즈 정리를 바탕으로 돌아가는 모델임. 그래서 베이즈 정리부터 끌어옴.
P(x | y) = P(y | x) * P(x) / P(y)
여기서 우리가 구하고 싶은 건 문서 d
가 주어졌을 때, 어떤 클래스 c
에 속할 확률 P(c | d)
임.
근데 이걸 직접 구하기 어렵고, 베이즈 정리를 쓰면 다음처럼 바꿔쓸 수 있음:
P(c | d) = P(d | c) * P(c) / P(d)
이걸로 각 클래스별로 확률을 계산하고, 그 중 제일 높은 걸 고르면 되는 구조임:
c' = argmax_c P(c | d) = argmax_c P(d | c) * P(c) / P(d)
여기서 P(d)는 클래스마다 똑같이 들어가니까 그냥 무시해도 됨. 그래서 최종식은 이렇게 됨:
c' = argmax_c P(d | c) * P(c)
즉, 각 클래스에 대해서
1. 그 클래스 자체의 확률(Prior)
2. 문서가 그 클래스에서 등장할 가능성(Likelihood)
을 곱해서 제일 높은 값 가진 클래스를 고르면 됨.
이게 바로 Naive Bayes의 핵심 구조
문서 → 각 단어의 빈도 기반 벡터 → 각 클래스에서의 확률 계산 → 가장 높은 확률 가진 클래스로 분류
이 흐름..
보통 문서를 벡터로 바꿈. 방법은 bag of words
라는 걸 많이 씀.
단어들의 등장 빈도만 보고 벡터로 바꿔서 계산에 씀. 순서는 신경 안 씀.
문장을 벡터(등장빈도)로 표현
- 이 방식의 특징
- 단어 순서 무시 → 간단하지만 문맥 정보 없음
- 단어별로 독립 가정 → 이게 Naive Bayes와 찰떡임
- 문서 간 비교 쉬움 → 어떤 단어가 얼마나 자주 나왔는지로 분류 가능
Naive Bayes가 어떻게 단어별 확률을 곱해서 전체 문서의 확률을 구하는지
문서를 bag of words
로 표현하면 결국 단어들로 이루어진 피처 셋이 생김.
즉, 하나의 문서는 단어들로 이루어진 피처 벡터라고 보면 됨:
{f1, f2, ..., fn}
이때 Naive Bayes는 단어들이 서로 독립이라고 가정함.
그래서 전체 문서가 어떤 클래스 c
에 속할 확률 P(f1, f2, ..., fn | c)
는 그냥 각 단어의 조건부 확률을 다 곱한 걸로 계산함:
P(f1, f2, ..., fn | c) = P(f1 | c) * P(f2 | c) * ... * P(fn | c)
이게 바로 "나이브"한 이유임. 진짜 단순하게 곱하기만 함.
그래서 최종 식은 이렇게 정리됨:
c' = argmax_c P(c) * Π P(f | c)
(f ∈ 문서 안의 단어들)
계산이 되게 쉬워지고, 속도도 빠름.
물론 단어들이 실제로는 독립이 아니니까 완전 정확하진 않지만, 그래도 꽤 괜찮게 맞음.
문서를 bag of words로 바꾼다
-> 각 단어가 클래스 c일 때 등장할 확률들을 곱한다
-> 각 클래스마다 그 값을 계산하고, 제일 큰 쪽으로 분류한다
- 확률을 계속 곱하다 보면 너무 작은 수가 나옴 (underflow 문제)
- 그래서 보통 로그를 씌워서 계산함.
- Naive Bayes는 결국
선형 분류기
로 볼 수 있음.
- (Log를 취하면 선형결합 형태로 바뀌기 때문)
- 곱하기가 로그를 만나면 더하기로 바뀜
naive bayes 는 linear 다. 라고 할 수 있음
logistic regression
decision boundary 가 선형으로 구분되기 때문에
선형분류에 이용될수있다는 거지 선형분류라고 하기는 좀 어렵다..
왜냐면 시그모이드함수가 선형이 아니기 때문
학습 데이터로부터 P(c)랑 P(w | c) 두 가지를 알아내야 함.
prior, likelyhood → 식에 대입 → feature prob 의 곱을 구하기
곱 → underflow → log 취하기(nemerical stability)
Prior: 각 클래스의 등장 비율 → P(c)
Likelihood: 각 단어가 클래스에서 나올 확률 → P(w | c)
이걸 문서에 있는 단어들에 대해 다 곱해서
→ P(c) * Π P(w | c) 계산
곱하면 underflow 나기 쉬움 → log 취해서
→ log P(c) + Σ log P(w | c) 로 계산
(숫자 안정성 + 계산 속도 ↑)
likelihood 계산을 실제로 어떻게 하는지
우리가 구해야 하는 건 특정 클래스 c에서 단어 w가 나올 확률 P(w | c)
임.
이걸 구하는 방법은 생각보다 간단함:
super-document
) 즉, 식으로 쓰면:
P(w | c) = count(w in 클래스 c) / 전체 단어 수 in 클래스 c
이렇게 하면 만약 어떤 단어가 한 번도 안 나왔으면 확률이 0이 됨 → 곱하면 전체도 0됨
그래서 Laplace Smoothing
을 씀. (1 더해서 확률이 0 되는 거 방지)
분모는 V(전체 vocabulary) 기준의 단어 수
→ 즉, 클래스 c에 안 나오는 단어들도 smoothing 때문에 고려됨
P(w | c) = (count(w, c) + 1) / (sum(count(w’, c)) + |V|)
Naive Bayes 모델을 사용할 때 주의해야 할 두 가지 처리 이슈가 있음. 바로 unknown word와 stop word임.
훈련 데이터
테스트 문장
Seoyeon told Mingyu she was soooo totally happy for him
클래스 분포에 따라 Prior 확률을 계산
stop words unknown word를 제거
각 단어가 Sarcastic 또는 Not Sarcastic 클래스에서 나올 확률을 계산한다. 이때 라플라스 스무딩을 적용한다 (count + 1 / 전체 단어 수 + V).
Naive Bayes 식을 그대로 적용해, 각 클래스에 대한 확률을 계산한다.
Sarcastic 클래스의 확률이 더 높기 때문에, 이 테스트 문장은 Sarcastic으로 분류된다.