Одна из частых тем, с которыми я сталкиваюсь, погружаясь в мир машинного обучения, - это наивный Байес; уравнение, которое не так наивно.

Эта статья пытается упростить математику, лежащую в основе полиномиального наивного байеса.

Полный код этой статьи можно найти здесь.

Что такое наивный Байес?

Наивный байесовский классификатор - это вероятностный классификатор, что означает, что этот подход использует вероятность и / или частоту для классификации.

Типичный пример (который мы проверим) - это классификация электронных писем для любительских / спам-сообщений. Классификатор просматривает наши помеченные спамом и любительскими письмами и классифицирует их на основе ранее наблюдаемой частоты употребления слов.

Этот «наивный» классификатор в этом сценарии несколько имитирует нас, людей; как я узнаю, что электронное письмо является спамом; из предыдущих писем! Я знаю, что электронное письмо от моего менеджера - «[email protected]» на основании предыдущих взаимодействий с этим электронным письмом или знаний, поэтому просмотр электронного письма от «[email protected]» может вызвать подозрение.

Уравнение ниже представляет наивный байесовский метод:

Разбивая приведенное выше уравнение, в нем говорится, что нужно найти argmax суммы предыдущего журнала и журнала вероятности получения нашего электронного письма.

Сглаживание.

Теперь мы понимаем, как работает наивный байесовский классификатор; но, присмотревшись к нему, мы обнаруживаем, что классификатор будет работать только с новыми электронными письмами, когда мы увидим этот пример, но тогда нам нужно будет сделать это для всех других слов в электронных письмах в будущем.

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

Прежний

Это вероятность события до того, как будут собраны новые данные. Наш предыдущий код приведен ниже:

def cal_prior_prob(self):
    total_count = len(self.spam_emails) + len(self.ham_emails)
    return log(len(self.spam_emails) / total_count),    log(len(self.ham_emails) / total_count)

Вероятность

Как гласит термин, это вероятность того, что слово в электронном письме будет поддерживать либо спам, либо ветчину. Он измеряет поддержку, предоставляемую данными для каждого возможного значения параметра.

Если мы сравним функцию правдоподобия в двухпараметрических точках и обнаружим, что L (θ1 | x) ›L (θ2 | x), то выборка, которую мы фактически наблюдали, с большей вероятностью имела место при θ = θ1, чем при θ = θ2. Это можно интерпретировать как θ1 более правдоподобное значение для θ, чем θ2.

Чтобы разбить формулу выше:

spam_likelihood = word_frequency / (total_spam + vocabulary)

Наш словарь будет уникальным общим количеством слов из наших электронных писем.

Чтобы обработать вариант использования невидимых слов, мы добавим альфа-значение для сглаживания, наше уравнение станет:

(word_frequency + alpha) / (total_spam + alpha * vocabulary)

Наша функция правдоподобия становится:

def find_dict_ham_likelihood(key):
    word_frequency = 0  # counter
    for word in spam_bag_words():
        word_frequency += 1
        total_spam = len(ham_word_list)
        ham_likelihood = (word_frequency + alpha) / (total_spam + alpha * vocabulary)
        dict_ham_likelihood[word.lower()] = ham_likelihood
    return dict_ham_likelihood[key]

Аргмакс

Это операция, которая находит аргумент, который дает максимальное значение целевой функции. Argmax чаще всего используется в машинном обучении для поиска класса с наибольшей предсказанной вероятностью. Мы будем реализовывать это с помощью оператора if:

if ham_probabilty >= spam_probabilty:
    return "ham"
else:
    return "spam"

Код

Попробуем поместить приведенные выше пояснения в код. Мы будем классифицировать группу писем как ветчину или спам; в нашем обучающем наборе 1000 спам- и любительских писем, разделенных поровну.

Сначала мы извлечем наши данные, удалим числа, дубликаты и сформируем наш пакет слов для спама и ветчины (обратите внимание, что у меня есть файлы локально, вы можете использовать nltk corpus и очищать свои данные больше):

Затем мы рассчитаем нашу вероятность (и):

Мы рассчитываем нашу априорную (ые):

Далее применяем правило Байеса:

Мы можем протестировать наш код на данный момент с образцом электронного письма, вызвав функцию Байеса, см. Пример ниже:

print(bayes("Good day, awaiting your response on the budget"))

Мы протестировали нашу функцию Байеса, и пока она работает, как ожидалось. Поздравляем, мы создали байесовскую наивную функцию. Приведенная ниже работа - это дополнительный шаг, который вы можете предпринять.

У меня есть несколько писем (спам и ветчина), и я хотел бы по-настоящему увидеть, насколько хороша или плоха наша функция. Мы отправим 99 новых тестовых писем против нашей службы и будем подсчитывать количество: Истинных положительных результатов (TP), истинно отрицательные (TN), ложные срабатывания (FP), ложные отрицания (FN); а также следующие показатели: Точность, отзывчивость, F-балл

Наш код выше также напечатал таблицу истинности, см. Изображение ниже: