Наивный байесовский алгоритм — это контролируемый алгоритм машинного обучения. Как следует из названия, он основан на теореме Байеса. В этом посте вы узнаете, что происходит за наивным байесовским классификатором, когда вы имеете дело с непрерывными переменными-предикторами.

Здесь я использовал язык R для кодирования. Давайте посмотрим, что происходит за кулисами в функции naiveBayes, когда функции или переменные-предикторы непрерывны по своей природе.

Прочная основа теоремы Байеса, а также функций вероятности (функция плотности и функция распределения) необходима, если вы действительно хотите получить представление об интуиции, лежащей в основе алгоритма наивного Байеса.

(Вы можете пропустить этот раздел, если вам нравится теорема Байеса, и вы можете перейти к следующему разделу «Как рассчитывается вероятность в Наивном Байесе?»)

Теорема Байеса касается нахождения вероятности (мы называем ее апостериорной вероятностью) на основе некоторых других вероятностей, которые мы знаем заранее.

Согласно теореме,

P(A|B) = P(A) P(B|A)/P(B)

  • P(A|B) и P(B|A) называются условными вероятностями, где P(A|B) означает, как часто происходит A при условии, что происходит B.
  • P(A) и P(B) называются предельными вероятностями, которые показывают, насколько вероятно A или B само по себе (вероятность события независимо от результатов других случайных величин)

P (A / B) - это то, что мы собираемся предсказать, поэтому также называется апостериорной вероятностью.

Теперь в реальном мире у нас было бы много переменных-предикторов и много переменных класса. Для простоты отображения давайте назовем эти классы как C1, C2,…, Ck и переменные-предикторы (векторы признаков) x1,x2,…,xn.

Тогда, используя теорему Байеса, мы будем измерять условную вероятность события с вектором признаков x1,x2,…,xn, принадлежащим определенному классу Ci.

Мы можем сформулировать апостериорную вероятность P(c|x) из P(c), P(x) и P(x|c), как указано ниже.

Но что, если есть функции с непрерывными значениями? Что за кулисами на самом деле делает наивный байесовский классификатор для прогнозирования вероятностей непрерывных данных?

Обычно мы используем пакет e1071 для создания наивного байесовского классификатора в R. А затем, используя этот классификатор, мы делаем некоторые прогнозы на основе обучающих данных.

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

Это не что иное, как использование функций плотности вероятности. Итак, здесь Наивный байесовский метод генерирует распределение Гаусса (нормальное) для каждой переменной-предиктора. Распределение характеризуется двумя параметрами: средним значением и стандартным отклонением. Затем на основе среднего значения и стандартного отклонения каждой переменной-предиктора вероятность того, что значение будет «x», рассчитывается с использованием функции плотности вероятности. (Функция плотности вероятности дает вероятность наблюдения измерения с определенным значением)

Нормальное распределение (гауссовая кривая) имеет плотность

где μ — среднее значение распределения, а σ — стандартное отклонение.

функция dnorm в R

f(x) или функцию плотности вероятности для значения «x» можно рассчитать, используя некоторые стандартные вычисления z-таблицы, или на языке R у нас есть функция dnorm.

функция dnorm в R является основой непрерывного наивного Байеса.

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

Вы можете отразить то, что делает функция naiveBayes, используя функцию dnorm (x, mean=, sd=) для каждого класса результатов. (помните, что переменная класса является категориальной, а функции могут быть сочетанием непрерывных и категориальных). dnorm вR дает нам функцию плотности вероятности.

Рассмотрим данные Iris на языке R.

Набор данных Iris содержит три вида растений ( setosa,viriginica,versicolor) и четыре признака ( Sepal.Length, Sepal.Width, Petal.Length, Petal.Width) , измеренные для каждого образца.

Сначала мы построим модель, используя функцию Naive Bayes в пакете e1071. А затем, учитывая набор признаков, скажем, Sepal.Length=6,9, Sepal.Width=3,1, Petal.Length=5,0, Petal.Width=2,3, мы предскажем, каким будет вид.

А теперь самое интересное — что происходит за кулисами:

Итак, вот полный код, использующий функцию naiveBayes для предсказания вида.

#Установка пакета e1071 R

установить.пакеты('e1071')

библиотека (e1071)

# Читаем набор данных

данные («радужная оболочка»)

#изучение структуры данных

ул(ирис)

# Разделение набора данных на обучающий набор и тестовый набор

split=sample.split(диафрагма,SplitRatio=0,7)

Тренировочный набор = подмножество (радужная оболочка, разделение == ИСТИНА)

Набор тестов = подмножество (радужная оболочка, разделение == ЛОЖЬ)

# Подгонка модели naïve_bayes к тренировочному набору

install.packages('caTools')

библиотека («caTools»)

набор.сид(120)

classifier = naiveBayes (x = Trainingset [, -5], y = Trainingset $ Виды)

классификатор

# Предсказание на тестовых данных

Y_Pred = прогноз (классификатор, новые данные = набор тестов)

Y_Pred

# Матрица путаницы

см = таблица (набор тестов $ виды, Y_Pred)

cm

#Задача: по заданному набору признаков найти, к какому виду он принадлежит

#определение нового набора данных (признаков) для проверки классификации

sl=6.9

sw=3.1

pl=5.0

pw=2.3

newfeatures=data.frame(Sepal.Length=sl,Sepal.Width=sw,Petal.Length=pl,Petal.Width=pw)

Y_Pred = прогноз (классификатор, новые данные = новые функции)

Y_Pred

Теперь при выполнении кода вы можете видеть, что предсказанный вид - это Virginica в соответствии с функцией naiveBayes.

Мы знаем, что Наивный Байес предсказывает результаты, используя функции плотности вероятности в конце.

Мы собираемся сразу узнать вероятности, используя функцию dnorm для каждой переменной класса. Результат должен быть таким же, как предсказанный функцией naiveBayes.

Для заданного набора признаков

  1. На основе среднего значения и стандартного отклонения будет получена условная вероятность.
  2. А затем, применив теорему Байе, вероятность для каждого вида при заданном наборе переменных-предикторов будет получена и сравнена друг с другом.
  3. Предсказанным результатом будет тот, который имеет более высокую вероятность.

Вот полный код для использования предсказания вручную (с функцией dnorm)

установить.пакеты('e1071')

библиотека (e1071)

# Чтение набора данныхdata("iris")

#изучение структуры данныхstr(iris)

# Разделение набора данных на обучающий набор и тестовый набор

split=sample.split(диафрагма,SplitRatio=0,7)

Тренировочный набор = подмножество (радужная оболочка, разделение == ИСТИНА)

Набор тестов = подмножество (радужная оболочка, разделение == ЛОЖЬ)

# Подгонка модели naïve_bayes к тренировочному набору

install.packages('caTools')

библиотека («caTools»)

набор.сид(120)

classifier=naiveBayes(x = Trainingset[,-5],y = Trainingset$Species)

#Задача: по заданному набору признаков найти, к какому виду он принадлежит

#определение нового набора данных (признаков) для проверки классификации

sl=6.9

sw=3.1

pl=5.0

pw=2.3

#Нахождение априорных вероятностей класса каждого вида

PriorProb_Setosa = среднее (Trainingset $ Species == 'setosa')

PriorProb_Virginica = означает (Trainingset $ Species == 'virginica')

PriorProb_versicolor = среднее значение (Trainingset $ Species == 'versicolor')

# Среднее значение вида и стандартное отклонение длины чашелистика

#Нахождение условных вероятностей или правдоподобия или априорных вероятностей

Setosa = подмножество (Trainingset, Trainingset $ Species == 'setosa')

Virginica = подмножество (Trainingset, Trainingset $ Species == 'virginica')

Versicolor= subset(Trainingset, Trainingset$Species=='versicolor')

Set=Setosa%›%summarise(mean(Sepal.Length),среднее(Sepal.Width),среднее(Petal.Length),среднее(Petal.Width),sd(Sepal.Length),sd(Sepal.Width), sd(Лепесток.Длина),sd(Лепесток.Ширина))

Vir=Virginica%›% суммировать(среднее(Sepal.Length),среднее(Sepal.Width),среднее(Petal.Length),среднее(Petal.Width),sd(Sepal.Length),sd(Sepal.Width), sd(Лепесток.Длина),sd(Лепесток.Ширина))

Ver=Versicolor%›% summarise(mean(Sepal.Length),среднее(Sepal.Width),среднее(Petal.Length),среднее(Petal.Width),sd(Sepal.Length),sd(Sepal.Width), sd(Лепесток.Длина),sd(Лепесток.Ширина))

Set_sl=dnorm(sl,mean=Set$`mean(Sepal.Length)`, sd=Set$`sd(Sepal.Length)`)

Set_sw=dnorm(sw,mean=Set$`mean(Sepal.Width)`, sd=Set$`sd(Sepal.Width)`)

Set_pl=dnorm(pl,mean=Set$`mean(Petal.Length)`, sd=Set$`sd(Petal.Length)`)

Set_pw=dnorm(pw,mean=Set$`mean(Petal.Width)`, sd=Set$`sd(Petal.Width)`)

#знаменатель будет одинаковым для всех трех вероятностей. ТАК мы можем игнорировать их в расчетах

Вероятность бытьSetosa =Set_sl*Set_sw*Set_pl*Set_pw*PriorProb_Setosa

Vir_sl=dnorm(sl,mean=Vir$`mean(Sepal.Length)`, sd=Vir$`sd(Sepal.Length)`)

Vir_sw=dnorm(sw,mean=Vir$`mean(Sepal.Width)`, sd=Vir$`sd(Sepal.Width)`)

Vir_pl=dnorm(pl,mean=Vir$`mean(Petal.Length)`, sd=Vir$`sd(Petal.Length)`)

Vir_pw=dnorm(pw,mean=Vir$`mean(Petal.Width)`, sd=Vir$`sd(Petal.Width)`)

Вероятность быть Вирджинией = Vir_sl*Vir_sw*Vir_pl*Vir_pw*PriorProb_Virginica

Ver_sl=dnorm(sl,mean=Ver$`mean(Sepal.Length)`, sd=Ver$`sd(Sepal.Length)`)

Ver_sw=dnorm(sw,mean=Ver$`mean(Sepal.Width)`, sd=Ver$`sd(Sepal.Width)`)

Ver_pl=dnorm(pl,mean=Ver$`mean(Petal.Length)`, sd=Ver$`sd(Petal.Length)`)

Ver_pw=dnorm(pw,mean=Ver$`mean(Petal.Width)`, sd=Ver$`sd(Petal.Width)`)

Вероятность бытьVersicolor=Ver_sl*Ver_sw*Ver_pl*Ver_pw*PriorProb_versicolor

Вероятность быть Сетосой

Вероятность быть Виргиной

Вероятность быть разноцветным

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

Априорные вероятности и условные вероятности

Когда вы запускаете сценарии в R для непрерывных/числовых переменных, вы могли видеть таблицы с названиями априорных вероятностей и условных вероятностей. Скриншот из консоли приведен ниже

В таблице под названием «Априорные вероятности» указана априорная вероятность для каждого класса (P(c)) в вашем обучающем наборе. Это дает распределение классов в данных («A priori» на латыни означает «сначала»), которое можно сразу рассчитать на основе количества вхождений, как показано ниже:

P(c) = n(c)/n(S), где P(c) — вероятность события «c», n(c) — количество благоприятных исходов. n(S) — общее количество событий в выборочном пространстве.

Данная таблица условных вероятностей показывает не вероятности, а параметры распределения (точнее среднее и стандартное отклонение непрерывных данных). Помните, что если бы признаки были категориальными, эта таблица указывала бы само значение вероятности.

Некоторые дополнительные моменты, о которых следует помнить

1. Вместо того, чтобы вычислять таблицы вручную, вы можете просто использовать сами результаты naiveBayes.

Здесь, в приведенном выше сценарии с использованием dnorm, я вычислил среднее значение и стандартное отклонение вручную. Вместо этого вы можете получить его, используя простой код.

Например, если вы хотите увидеть среднее значение и стандартное отклонение длины чашелистика для каждого вида, просто запустите этот

›классификатор$таблицы$Sepal.Length

2. Отбрасывание знаменателя (p(x)) вероятностей в расчетах.

Вы заметили, что я опустил значение знаменателя в расчетах вероятностей?

Потому что знаменатель (p (x)) будет одинаковым для всех, когда мы сравниваем вероятности для каждого класса по указанным функциям. Так что мы можем просто избавиться от этого. Нам просто нужно сравнить верхние части расчета. Также имейте в виду, что мы сравниваем только вероятности и, следовательно, опускаем знаменатель. Если нам нужно получить фактическое значение вероятности, знаменатель не должен быть опущен.

3. Что делать, если непрерывные данные не распределены нормально?

Конечно, есть и другие распределения, такие как Бернулли, полиномиальное и т. д., а не только распределение Гаусса. Но логика за всеми одна и та же: предполагается, что функция удовлетворяет определенному распределению, оцениваются параметры распределения, а затем получается функция плотности вероятности.

4. Плотность на основе ядра

Плотности на основе ядра могут работать лучше, когда непрерывные переменные не распределены нормально. Это может повысить точность теста. При создании модели введите этот код ‘useKernel=T’

5. Стратегия дискретизации для непрерывных наивных баев.

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

6. Почему Naivebayes называют Naive?

Алгоритм Наивного Байеса называется «Наивным», потому что он предполагает, что возникновение определенного признака не зависит от появления других признаков, хотя на самом деле они могут каким-то образом зависеть!

Первоначально опубликовано на https://qualitynotion.com 17 декабря 2020 г.