Что такое Naive Bayes классификатор?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Naive Bayes классификатор?
Naive Bayes — это простой, но мощный вероятностный алгоритм классификации, основанный на теореме Байеса и предположении условной независимости признаков. Несмотря на своё наивное предположение, он часто работает удивительно хорошо и остаётся популярным для многих задач, особенно для классификации текстов.
Основная идея
Теорема Байеса:
P(Class|Features) = P(Features|Class) * P(Class) / P(Features)
Где:
- P(Class|Features) — апостериорная вероятность (что мы хотим найти)
- P(Features|Class) — правдоподобие (likelihood)
- P(Class) — априорная вероятность класса
- P(Features) — вероятность признаков (свидетельство)
Ключевое предположение: Условная независимость
Наивное предположение: все признаки условно независимы друг от друга при известном классе.
P(x1, x2, x3, ..., xn | Class) = P(x1|Class) * P(x2|Class) * ... * P(xn|Class)
Это предположение часто неверно в реальности, но это делает алгоритм вычислительно эффективным.
import numpy as np
from sklearn.naive_bayes import GaussianNB, MultinomialNB, BernoulliNB
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
# Загрузка данных
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Создание и обучение модели
gnb = GaussianNB()
gnb.fit(X_train, y_train)
# Предсказание
y_pred = gnb.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Точность: {accuracy:.4f}")
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")
Вычисление апостериорной вероятности
# Для каждого класса вычисляем вероятность
from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB()
gnb.fit(X_train, y_train)
# Получаем вероятности для каждого класса
y_proba = gnb.predict_proba(X_test)
print(y_proba[:5]) # Вероятности для первых 5 примеров
# Например, для первого примера:
# [0.01, 0.98, 0.01] означает 98% вероятность класса 1
# Логарифмы вероятностей (для избежания численной нестабильности)
log_proba = gnb.predict_log_proba(X_test)
print(log_proba[:5])
Типы Naive Bayes
1. Gaussian Naive Bayes
Для непрерывных признаков предполагаем гауссово распределение.
from sklearn.naive_bayes import GaussianNB
# Для каждого класса вычисляются mean и variance
gnb = GaussianNB()
gnb.fit(X_train, y_train)
print("Средние значения для каждого класса:")
for i, class_label in enumerate(gnb.classes_):
print(f"Класс {class_label}: {gnb.theta_[i]}")
print("\nДисперсия для каждого класса:")
for i, class_label in enumerate(gnb.classes_):
print(f"Класс {class_label}: {gnb.var_[i]}")
# При предсказании используется формула гауссова распределения:
# P(xi|Class) = 1/(sqrt(2*pi*sigma^2)) * exp(-(xi - mu)^2 / (2*sigma^2))
2. Multinomial Naive Bayes
Для дискретных признаков (часто используется для текстов, где признаки — количество слов).
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer
# Пример: классификация текстов
corpus = [
"This is a good movie",
"This movie is terrible",
"I love this film",
"Worst movie ever"
]
y = [1, 0, 1, 0] # 1 = positive, 0 = negative
# Преобразование текста в матрицу количеств
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
# Обучение
mnb = MultinomialNB(alpha=1.0) # alpha — сглаживание Лапласа
mnb.fit(X, y)
# Предсказание
test_text = "This is a good film"
X_test = vectorizer.transform([test_text])
prediction = mnb.predict(X_test)
print(f"Предсказание: {prediction[0]}")
print(f"Вероятности: {mnb.predict_proba(X_test)[0]}")
3. Bernoulli Naive Bayes
Для бинарных признаков (например, присутствие/отсутствие слова в документе).
from sklearn.naive_bayes import BernoulliNB
from sklearn.feature_extraction.text import TfidfVectorizer
# Пример: классификация с бинарными признаками
corpus = [
"This is a good movie",
"This movie is terrible",
"I love this film",
"Worst movie ever"
]
y = [1, 0, 1, 0]
# TfidfVectorizer с binary=True
vectorizer = TfidfVectorizer(binary=True)
X = vectorizer.fit_transform(corpus)
# Обучение
bnb = BernoulliNB(alpha=1.0)
bnb.fit(X, y)
# Предсказание
test_text = "good film"
X_test = vectorizer.transform([test_text])
prediction = bnb.predict(X_test)
print(f"Предсказание: {prediction[0]}")
Вручную: пошаговое вычисление
import numpy as np
from collections import Counter
class NaiveBayesManual:
def fit(self, X, y):
"""
Обучение: вычисляем P(Class) и P(Feature|Class)
"""
self.classes = np.unique(y)
self.class_prior = {} # P(Class)
self.feature_likelihood = {} # P(Feature|Class)
for class_label in self.classes:
# Примеры для этого класса
X_class = X[y == class_label]
# P(Class) = количество примеров класса / всего примеров
self.class_prior[class_label] = len(X_class) / len(X)
# Для каждого признака вычисляем P(Feature|Class)
self.feature_likelihood[class_label] = {}
for feature_idx in range(X.shape[1]):
feature_values = X_class[:, feature_idx]
# Среднее и дисперсия для гауссова распределения
self.feature_likelihood[class_label][feature_idx] = {
'mean': feature_values.mean(),
'variance': feature_values.var()
}
def _gaussian_probability(self, x, mean, variance):
"""
Вычисляет P(x|mean, variance) для гауссова распределения
"""
numerator = np.exp(-(x - mean) ** 2 / (2 * variance))
denominator = np.sqrt(2 * np.pi * variance)
return numerator / denominator
def predict(self, X):
"""
Предсказание для новых примеров
"""
predictions = []
for x in X:
posteriors = {} # P(Class|x)
for class_label in self.classes:
# Начинаем с априорной вероятности
posterior = self.class_prior[class_label]
# Умножаем на вероятность каждого признака
for feature_idx, feature_value in enumerate(x):
likelihood_params = self.feature_likelihood[class_label][feature_idx]
posterior *= self._gaussian_probability(
feature_value,
likelihood_params['mean'],
likelihood_params['variance']
)
posteriors[class_label] = posterior
# Выбираем класс с максимальной вероятностью
prediction = max(posteriors, key=posteriors.get)
predictions.append(prediction)
return np.array(predictions)
# Использование
nb = NaiveBayesManual()
nb.fit(X_train, y_train)
y_pred = nb.predict(X_test)
accuracy = np.mean(y_pred == y_test)
print(f"Точность: {accuracy:.4f}")
Преимущества Naive Bayes
- Простота: легко понять и реализовать
- Скорость: очень быстро обучается и предсказывает
- Эффективность: хорошо работает на высокомерных данных
- Мало данных: хорошо работает с маленькими датасетами
- Вероятности: естественным образом выдаёт вероятности
- Параллелизм: легко распараллеливается
Недостатки Naive Bayes
- Наивное предположение: редко бывает верным в реальности
- Корреляция признаков: не учитывает зависимость между признаками
- Нулевые вероятности: если признак не появился в обучении, вероятность становится 0
- Решение: сглаживание Лапласа (alpha > 0)
Практический пример: Классификация спама
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# Простой датасет
emails = [
"Buy now get 50% off",
"Meeting at 10 am",
"Limited offer click here",
"Project update attached",
"URGENT: claim your prize",
"Quarterly results enclosed"
]
y = [1, 0, 1, 0, 1, 0] # 1 = spam, 0 = ham
X_train, X_test, y_train, y_test = train_test_split(
emails, y, test_size=0.3, random_state=42
)
# Pipeline: TF-IDF + Naive Bayes
pipeline = Pipeline([
('tfidf', TfidfVectorizer(lowercase=True, stop_words='english')),
('clf', MultinomialNB())
])
pipeline.fit(X_train, y_train)
# Оценка
y_pred = pipeline.predict(X_test)
print(classification_report(y_test, y_pred, target_names=['Ham', 'Spam']))
# Предсказание для новой почты
new_email = "Win free tickets now"
prediction = pipeline.predict([new_email])
proba = pipeline.predict_proba([new_email])
print(f"Email: {new_email}")
print(f"Prediction: {'Spam' if prediction[0] == 1 else 'Ham'}")
print(f"Probabilities: Ham={proba[0][0]:.2f}, Spam={proba[0][1]:.2f}")
Когда использовать Naive Bayes
- Классификация текстов (spam detection, sentiment analysis)
- Классификация с высокой размерностью
- Быстрое прототипирование
- Baseline модель для сравнения
- Когда нужны вероятности, а не просто предсказания
- Когда данных мало
Вывод: Naive Bayes — это простой, быстрый и часто неожиданно эффективный алгоритм. Несмотря на его наивное предположение, он остаётся отличным выбором для многих практических задач, особенно для классификации текстов. Он служит хорошей baseline моделью для сравнения с более сложными методами.