Одна из частых тем, с которыми я сталкиваюсь, погружаясь в мир машинного обучения, - это наивный Байес; уравнение, которое не так наивно.
Эта статья пытается упростить математику, лежащую в основе полиномиального наивного байеса.
Полный код этой статьи можно найти здесь.
Что такое наивный Байес?
Наивный байесовский классификатор - это вероятностный классификатор, что означает, что этот подход использует вероятность и / или частоту для классификации.
Типичный пример (который мы проверим) - это классификация электронных писем для любительских / спам-сообщений. Классификатор просматривает наши помеченные спамом и любительскими письмами и классифицирует их на основе ранее наблюдаемой частоты употребления слов.
Этот «наивный» классификатор в этом сценарии несколько имитирует нас, людей; как я узнаю, что электронное письмо является спамом; из предыдущих писем! Я знаю, что электронное письмо от моего менеджера - «[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-балл
Наш код выше также напечатал таблицу истинности, см. Изображение ниже: