← Назад к вопросам

Что такое Naive Bayes классификатор?

1.0 Junior🔥 151 комментариев
#Машинное обучение#Статистика и A/B тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое 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

  1. Простота: легко понять и реализовать
  2. Скорость: очень быстро обучается и предсказывает
  3. Эффективность: хорошо работает на высокомерных данных
  4. Мало данных: хорошо работает с маленькими датасетами
  5. Вероятности: естественным образом выдаёт вероятности
  6. Параллелизм: легко распараллеливается

Недостатки Naive Bayes

  1. Наивное предположение: редко бывает верным в реальности
  2. Корреляция признаков: не учитывает зависимость между признаками
  3. Нулевые вероятности: если признак не появился в обучении, вероятность становится 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 моделью для сравнения с более сложными методами.