Добрый день, уважаемые читатели. Сегодня мы разберём уникальный алгоритм машинного обучения — наивный Байесовский классификатор. Без математики здесь не обойтись, поэтому сразу приступаем.
Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!
Теорема Байеса и наивное предположение
Весь алгоритм построен на теореме Байеса — одной из фундаментальных теорем теории вероятностей. Звучит она следующим образом:
Для читателей, незнакомых с нотацией, приведенной выше, привожу список пояснений каждой части теоремы:
— вероятность гипотезы А при наступлении события В, т. е. вероятность А, когда В уже верно;
— вероятность наступления события В, если гипотеза А верна;
— вероятность того, что гипотеза А верна;
— вероятность наступления события В;
В задачах классификации данная теорема рассматривается следующим образом:
В — один набор признаков (sample). А — вероятность того, что набор В принадлежит к определенному классу.
Также, отбросим знаменатель, так как в нашем случае он является константным.
Рассматривая каждый признак, наш классификатор выглядит следующим образом:
И теперь наступает время для «наивного» предположения — именно отсюда алгоритм наивной классификации и взял своё название. Предположим, что никак не коррелируют между собой, и тогда наша «идея» классификации выглядит следующим образом:
Также вместо произведения стоит перейти к сумме логарифмов, во избежание слишком маленьких чисел, и тогда классификация выглядит как:
Теперь нам остается лишь вычислить и
, что и является обучением модели.
Реализация на Python
Теперь запрограммируем нашу математическую модель с помощью Python
. Для начала импортируем необходимые нам модули:
from collections import defaultdict
import numpy as np
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
Примечание. Придерживаемся правил РЕР8, и импортируем функции и классы из модуля стандартной библиотеки в самом начале, а затем все остальные.
Затем, подобая программному интерфейсу sklearn
, создадим класс модели:
class NaiveBayesClassifier(object):
def init(self):
self.__class_freq = defaultdict(lambda:0)
self.__feat_freq = defaultdict(lambda:0)
def fit(self, X, y):
# calculate classes and features frequencies
for feature, label in zip(X, y):
self.__class_freq[label] += 1
for value in feature:
self.__feat_freq[(value, label)] += 1
# normalizate values
num_samples = len(X)
for k in self.__class_freq:
self.__class_freq[k] /= num_samples
for value, label in self.__feat_freq:
self.__feat_freq[(value, label)] /= self.__class_freq[label]
return self
В методе fit
мы, благодаря классу defaultdict
из модуля collections
, так раз и вычисляем параметры модели.
Приступим к реализации предсказания модели:
def predict(self, X):
# return argmin of classes
return min(self.__class_freq.keys(),
key=lambda c : self.__calculate_class_freq(X, c))
def __calculate_class_freq(self, X, clss):
# calculate frequence for current class
freq = - np.log(self.__class_freq[clss])
for feat in X:
freq += - np.log(self.__feat_freq.get((feat, clss), 10 ** (-7)))
return freq
Примечание. Это самая простая реализация, код которой вы можете встретить во многих статьях и книгах ввиду её простоты. Я постарался привести данную реализацию под общий программный интерфейс, чего не делали другие авторы.
Вот и всё. Теперь осталось протестировать нашу модель. В качестве набора данных возьмем Iris
— самый первый и простой набор данных.
data = load_iris() X, y = data.data, data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) model = NaiveBayesClassifier().fit(X_train, y_train) predictions = [model.predict(x) for x in X_test] print(accuracy_score(predictions, y_test)) Output: 0.9666666666666667.
Неплохой результат, как для модели, написанного своими руками, при чём так минималистично.
Заключение
В сегодняшней статье мы рассмотрели наивный байесовский классификатор — один из фундаментальных алгоритмов машинного обучения. От теории мы перешли к программированию модели и совершили первое успешное обучение.
Если помимо вероятностного прогнозирования вас интересует линейная алгебра, советую прочитать статью «Линейная алгебра — программируем с NumPy».
А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.