Files
2nd/10_Wiki/Topics/AI_and_ML/Multinomial-Naive-Bayes.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

190 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: wiki-2026-0508-multinomial-naive-bayes
title: Multinomial Naive Bayes
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Multinomial NB, MNB, Text NB]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [naive-bayes, ml, text-classification, sklearn, baseline]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack: { language: python, framework: scikit-learn }
---
# Multinomial Naive Bayes
## 매 한 줄
**Multinomial NB**는 단어 카운트(혹은 TF-IDF) 입력에 다항 분포를 가정한 NB 변형으로, 텍스트 분류(스팸·뉴스·감성)의 빠르고 강력한 baseline이며 sklearn `MultinomialNB` 1줄로 학습된다.
## 매 핵심
### 1. 모델
각 클래스 c에 대해 단어 vocabulary 위 다항 분포 θ_c를 가정.
```
P(x|c) ∝ ∏_w θ_{c,w}^{x_w}
P(c|x) ∝ P(c) · ∏_w θ_{c,w}^{x_w}
log P(c|x) = log P(c) + Σ_w x_w · log θ_{c,w} ← log-space 안정
```
학습:
```
θ_{c,w} = (count(c,w) + α) / (Σ_w' count(c,w') + α·|V|) ← Laplace smoothing
```
α=1 (default) — Laplace, α<1 — Lidstone.
### 2. 입력 표현
- **Bag-of-Words** (CountVectorizer) — 정통적.
- **TF-IDF** (TfidfVectorizer) — 종종 더 좋은 성능, 하지만 엄밀히 다항 분포 가정 위반(연속값) — 그래도 실무에서 우수.
- **n-gram (1,2)** — 흔한 트릭.
### 3. 다른 NB 변형 비교
| 변형 | 입력 | 가정 | 사용처 |
|------|------|------|--------|
| **Gaussian NB** | 연속값 | 클래스별 정규분포 | 일반 분류 (수치 feature) |
| **Multinomial NB** | 카운트 (정수≥0) | 다항 분포 | 텍스트 |
| **Bernoulli NB** | 이진 (0/1) | 베르누이 | 짧은 문서, 단어 존재 여부 |
| **Complement NB** | 카운트 | MNB 변형 | imbalanced 텍스트 |
### 4. 장단점
**장점**: 학습 O(n·d), 추론 O(d), online 학습 가능 (`partial_fit`), 작은 데이터에서 견고, 해석 용이 (log-prob feature weight).
**단점**: 단어 독립 가정(naive) — 실제로는 위반, OOV(미등장 단어)에 smoothing 필요, TF-IDF는 분포 가정 위반.
### 5. 2026 위치
LLM embedding + linear probe가 NLP 정확도 SOTA를 차지하지만, **MNB는 여전히 baseline·엣지/모바일·해석 가능 분류기·라벨 noisy 환경**에서 강세. CPU에서 ms 단위 추론.
## 💻 패턴
```python
# 1. Quickstart — 20 newsgroups
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
data = fetch_20newsgroups(subset="train")
clf = Pipeline([("tfidf", TfidfVectorizer()), ("mnb", MultinomialNB(alpha=0.1))])
clf.fit(data.data, data.target)
```
```python
# 2. Predict + accuracy
from sklearn.metrics import accuracy_score
test = fetch_20newsgroups(subset="test")
pred = clf.predict(test.data)
print(accuracy_score(test.target, pred)) # ~0.85
```
```python
# 3. Bag-of-Words + n-gram
from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(ngram_range=(1, 2), min_df=2, max_features=50_000)
X = vec.fit_transform(corpus)
mnb = MultinomialNB(alpha=1.0).fit(X, y)
```
```python
# 4. Hyperparam search — alpha
from sklearn.model_selection import GridSearchCV
gs = GridSearchCV(MultinomialNB(), {"alpha": [0.01, 0.1, 0.5, 1.0]}, cv=5)
gs.fit(X, y)
print(gs.best_params_)
```
```python
# 5. Complement NB (imbalanced 데이터에 더 강함)
from sklearn.naive_bayes import ComplementNB
clf = ComplementNB(alpha=0.5).fit(X_train, y_train)
```
```python
# 6. Online (partial_fit) — streaming
mnb = MultinomialNB()
classes = np.unique(y_all)
for X_batch, y_batch in stream:
mnb.partial_fit(X_batch, y_batch, classes=classes)
```
```python
# 7. Top features per class (해석)
import numpy as np
feature_names = vec.get_feature_names_out()
for c, log_p in zip(mnb.classes_, mnb.feature_log_prob_):
top = np.argsort(log_p)[-10:]
print(f"class {c}: {feature_names[top]}")
```
```python
# 8. Spam classifier end-to-end
import pandas as pd
df = pd.read_csv("sms.csv") # cols: text, label (spam/ham)
X = TfidfVectorizer(stop_words="english", min_df=3).fit_transform(df.text)
y = (df.label == "spam").astype(int)
mnb = MultinomialNB(alpha=0.1).fit(X, y)
```
```python
# 9. ROC-AUC + class probability
from sklearn.metrics import roc_auc_score
proba = mnb.predict_proba(X_test)[:, 1]
print(roc_auc_score(y_test, proba))
```
```python
# 10. Persistence
import joblib
joblib.dump(clf, "mnb_pipeline.joblib")
loaded = joblib.load("mnb_pipeline.joblib")
```
## 매 결정 기준
| 상황 | 추천 |
|------|------|
| 텍스트 분류 baseline | **MNB + TF-IDF** — 5분 완성 |
| 짧은 문서 (트윗, 제목) | **Bernoulli NB** |
| imbalanced 텍스트 | **Complement NB** |
| 수치 feature | **Gaussian NB** |
| SOTA 정확도 필요 | **Transformer fine-tune** |
| 모바일/엣지 빠른 추론 | **MNB** (수 KB 모델) |
| 해석 가능성 중요 | **MNB** (단어별 log-prob) |
## 🔗 Graph
- 부모: [[Naive-Bayes-Classifiers]]
- 응용: [[Sentiment Analysis]]
- Adjacent: [[TF-IDF]]
## 🤖 LLM 활용
- LLM에 "이 MNB classifier가 X를 spam으로 잘못 분류한 이유를 top feature 가중치로 설명" — 디버깅.
- LLM이 라벨링 → 작은 MNB가 추론 (지식 distillation의 단순 형태).
## ❌ 안티패턴
- **음수 feature를 MNB에 입력**: MNB는 비음수 가정 — 에러.
- **alpha=0**: zero count → log(0) = -inf → NaN. 항상 alpha>0.
- **dense feature**: MNB는 sparse 텍스트가 강점. dense 수치 → Gaussian NB.
- **단어 순서 무시 무시**: bag-of-words는 "not good"과 "good not" 동일 — bigram or transformer.
## 🧪 검증 / 중복
- 검증: sklearn docs, McCallum & Nigam (1998).
- 중복: [[Naive-Bayes-Classifiers]] (parent overview) — 본 문서는 Multinomial 전용.
## 🕓 Changelog
- 2026-05-10: 신규 작성. MNB 모델/Laplace/sklearn 패턴/Complement NB 비교/2026 위치.