Кейс 2. Спам-фильтр на словах (Bernoulli Naive Bayes)

Связать с реальным ML

Этот кейс – классика машинного обучения. Именно на задаче фильтрации спама наивный Байес десятилетиями показывал удивительно хорошую практическую эффективность. И что особенно важно – здесь максимально ясно видно, почему он работает, несмотря на наивное предположение о независимости признаков.

Цель кейса

Показать, как:

  • текст превращается в признаки

  • каждое слово становится независимым доказательством

  • логарифмы превращают произведение вероятностей в линейную сумму

  • простейшая модель решает реальную задачу

Здесь мы используем вариант Bernoulli Naive Bayes – модель, где важен не счет слов, а сам факт их присутствия.

Сценарий

Мы строим примитивный спам-фильтр.

Есть два класса:

  • spam

  • ham (обычное письмо)

Модель учитывает только одно:

слово либо есть в письме, либо его нет.

Частота появления слова внутри письма не имеет значения. Это и есть ключевая особенность Bernoulli-подхода.

Обучающая выборка

Каждое письмо – это набор слов.

Никакой грамматики, порядка слов или контекста мы не учитываем.

Шаг 1. Подсчет априорных вероятностей

Мы получаем P(spam)P(spam) и P(ham)P(ham).

Если спама больше – модель будет к нему априори склоняться.

Шаг 2. Подсчет условных вероятностей слов

Здесь мы оцениваем: P(wordclass)P(word \mid class)

Например:

  • P("free"spam)P("free" \mid spam)

  • P("meeting"ham)P("meeting" \mid ham)

Каждое слово рассматривается отдельно – это и есть предположение условной независимости.

Шаг 3. Классификация нового письма

Допустим, пришло письмо:

В нем одновременно есть слово, типичное для спама, и слово, характерное для обычной переписки.

Теперь считаем логарифмы вероятностей:

Сравниваем:

  • spam = -3.3479

  • ham = -3.7534

-3.34 > -3.75 → модель выбирает spam

Модель:

  1. Берет априорную вероятность класса.

  2. Добавляет вклад каждого слова.

  3. Выбирает класс с максимальным значением.

Что здесь важно понять

1. Каждое слово – условно независимое доказательство при фиксированном классе

Слово "free" голосует за spam.

Слово "meeting" голосует за ham.

Итог – сумма этих голосов в лог-пространстве. Это буквально раздел "Голосование признаков" из теоретической главы.

2. Произведение превращается в линейную модель

Формально:

P(Cwords)P(C)iP(wordiC)P(C \mid \text{words}) \propto P(C) \cdot \prod_{i} P(\text{word}_i \mid C)

После логарифмирования:

logP(Cwords)logP(C)+ilogP(wordiC)\log P(C \mid \text{words}) \propto \log P(C) + \sum_{i} \log P(\text{word}_i \mid C)

Это уже линейная сумма. Именно поэтому наивный Байес часто ведет себя как линейный классификатор (в лог-пространстве модель эквивалентна линейному классификатору по признакам).

3. Почему модель работает несмотря на наивность

В реальности слова зависимы:

  • "free" и "win" часто встречаются вместе

  • "meeting" и "project" коррелируют

Но для классификации нам важна не идеальная оценка вероятностей, а правильное сравнение классов. Ошибки из-за зависимостей часто распределяются симметрично и не меняют итоговый выбор.

Ограничения текущей реализации

В этом примере:

  • нет сглаживания (Laplace smoothing)

  • не учитывается отсутствие слов

  • в ручной реализации словарь явно не фиксируется (в отличие от примера с RubixML)

  • данные крайне малы

Это демонстрационная версия, цель которой – показать механику.

chevron-rightКейс 2. Полный пример кода на чистом PHPhashtag

Та же задача с использованием RubixML

Теперь посмотрим, как выглядит тот же самый процесс через библиотеку.

Как видите, результат такой же как и в примере с чистым PHP.

Здесь:

  • каждое слово стало бинарным признаком

  • 1 – означает присутствие

  • 0 – отсутствие

  • RubixML автоматически считает частоты и применяет формулу Байеса

С точки зрения логики – ничего не изменилось. Изменился только уровень абстракции.

Выводы

Этот кейс показывает три фундаментальные вещи.

Во-первых, наивный Байес идеально подходит для текстовых задач, где признаки естественно бинарны.

Во-вторых, модель работает как механизм суммирования доказательств. Каждый признак добавляет небольшой вклад, и итоговое решение – это их совокупность.

В-третьих, простота модели – не недостаток, а преимущество. Именно благодаря этой простоте наивный Байес десятилетиями оставался одним из базовых инструментов в задачах фильтрации спама.

Если после этого кейса становится ясно, что спам-фильтр – это не "искусственный интеллект", а аккуратная работа с вероятностями, значит, глава достигла своей цели.

circle-info

Чтобы самостоятельно протестировать этот код, воспользуйтесь онлайн-демонстрациейarrow-up-right для его запуска.

Last updated