Сегодня мы узнаем о компетенции очень «наивного» алгоритма, известного как Наивный Байес. Мы также обсудим его реализацию (с нуля) в наборе данных, содержащем как категориальные, так и непрерывные значения.

Введение

Наивный Байес — это алгоритм обучения с учителем, используемый для задач классификации. Он происходит из семейства «вероятностных классификаторов» и применяет теорему Байеса для классификации объектов с предположением, что все признаки независимы друг от друга. Это предположение делает его «наивным», потому что в реальной жизни очень маловероятно найти наборы данных, которые не имеют мультиколлинеарности или нулевой корреляции между предикторами.

Несмотря на это предположение, он неплохо справляется с классификацией объектов.

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

Теорема Байеса

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

Условная возможность:

Условная вероятность означает вероятность того, что событие произойдет при выполнении некоторого условия. Он представлен как P (событие | условие).

Давайте разберемся на «очень сложном» примере.

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

Наш пример будет представлен как P("больные руки"|"пробить стену").

Следует отметить, что,

P("ушибить руки"|"ударить кулаком по стене") ≠P("ударить кулаком по стене"|"ушибить руки")

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

Возвращаясь к теореме Байеса…

Эта теорема была введена нижеследующим джентльменом:

Это дает нам способ вычисления условной вероятности.

Математически это можно описать как

Много раз нам не давали значение знаменателя P(B)(этот термин также известен как доказательство). Мы можем рассчитать это, используя следующее уравнение:

P(B) = P(B|A)*P(A) + P(B|не A)*P(не A)

Обратите внимание:

  • Р(не А) = 1-Р(А)
  • P(B|не A) = 1-P(не B|не A)

Используя приведенное выше уравнение, мы получаем новую формулировку теоремы Байеса:

P(A|B) = P(B|A)*P(A)/(P(B|A)*P(A) + P(B|не A)*P(не A))

Работа Наивного Байеса на примере:

  • Найдите разные классы/группы в нашей переменной ответа. В нашем примере переменная ответа — «грипп?» и делится на 2 класса: «Да» и «Нет».
  • Для каждой переменной-предиктора мы определяем различные типы значений, которые она имеет. Например, для столбцов «озноб», «лихорадка» и «насморк» имеют значения типов: «Да» и «Нет»; для столбца «головная боль» есть «Легкая», «Нет» и «Сильная».
  • Для каждого типа значения в конкретном предикторе мы узнаем их «вероятность» отнесения к определенному классу переменной отклика. Например,

В случае, если у кого-то грипп, какова вероятность того, что у него легкая головная боль или P (головные боли = «легкая» | грипп = «да»)?

Общее количество строк, имеющих (головные боли = «легкие»), равно 3. Из этих трех строк мы видим, что 2 из них относятся к классу «да» в «гриппе?» столбец.

Следовательно, P(головные боли = «легкие» | грипп = «да») = 2/3

Аналогично вычисляем остальные:

Учитывая, что грипп = "да" (вероятность):

  • P(головные боли= "легкая"|грипп = "да") = 2/3,
  • P(головные боли= "нет" |грипп = "да") = 1/2
  • P(головные боли= "сильные"|грипп = "да")=2/3
  • P(озноб= "да"|грипп = "да") = 3/4 и P(озноб= "нет"|грипп = "да") = 2/4
  • P(насморк= "да"|грипп = "да") = 4/5 и P(насморк= "нет"|грипп = "да") = 1/3
  • P(лихорадка= "да"|грипп = "да") = 4/5 и P(лихорадка= "нет"|грипп = "да") = 1/3

Учитывая, что грипп = «нет»(вероятность):

  • P(головные боли= "легкая"|грипп = "нет") = 1/3
  • P(головные боли= "нет"|грипп = "нет") = 1/2
  • P(головные боли= "сильные"|грипп = "нет")=1/3
  • P(озноб= "да" |грипп = "нет") = 1/4и P(озноб= "нет"|грипп = "нет") = 2/4
  • P(насморк= "да" |грипп = "нет") = 1/5 и P(насморк= "нет"|грипп = "нет") = 2/3
  • P(лихорадка= "да"|грипп = "нет") = 1/5 и P(лихорадка= "нет"|грипп = "нет") = 2/3

Другие вероятности:

  • P(грипп = "да") = 5/8 и P(грипп = "нет") = 3/8
  • P(озноб = «да») = 4/8 и P(озноб = «нет») = 4/8
  • P(головная боль= "умеренная") = 3/8 ; P(головная боль= «сильная») = 3/8 и P(головная боль= «нет») = 2/8
  • P(насморк = «да») = 5/8 и P(насморк = «нет») = 3/8
  • P(лихорадка = «да») = 5/8 и P(лихорадка = «нет») = 3/8

Пример: Чтобы узнать вероятность заболеть гриппом при насморке (задний план), используя теорему Байеса.

  • P(грипп= "да"|насморк= "да") =

P(насморк: «да»|грипп= «да»)*P(грипп: «да») /P(насморк: «да»)

= ((4/5)*(5/8))/(5/8)=4/5

Теперь спрогнозируем, будет ли для данных условий у нас грипп или нет.

Пусть приведенное выше условие равно X. Нам нужно рассчитать:

  • P(грипп = «да»|X) = P(X|грипп = «да»)* P(грипп= «да»)/P(X)
  • P(грипп = "нет"|X) = P(X|грипп = "нет")* P(грипп= "нет")/P(X)

Поскольку P(X) распространен, просто игнорируйте его.

Расчет P(грипп= «да»|X) = 5/8 * (3/4* 1/3 * 2/3 * 1/3) = 0,0347 путем умножения значений, приведенных ниже:

  • P(грипп = "да") = 5/8
  • P(озноб= "да"|грипп = "да") = 3/4
  • P(насморк= "нет"|грипп = "да") = 1/3
  • P(головные боли= "легкая"|грипп = "да") = 2/3
  • P(лихорадка= "нет"|грипп = "да") = 1/3

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

P(X₁, X₂, X₃,…Xₙ| «да») = P(X₁|«да»)*P(X₂|«да»)*P(X₃|«да»)….*P(Xₙ|“ да")

Аналогично рассчитываем для гриппа = «нет»,

Вычисление P (грипп = «нет» | X) = (3/8) * (1/4) * (2/3) * (1/3) * (2/3) = 0,0138

  • P(грипп = "нет") = 3/8
  • P(озноб= "да" |грипп = "нет") = 1/4
  • P(насморк= "нет"|грипп = "нет") = 2/3
  • P(головные боли= "легкая"|грипп = "нет") = 1/3
  • P(лихорадка= "нет"|грипп = "нет") = 2/3

Поскольку P(X|грипп= «нет») ‹ P(X|грипп= «да»), весьма вероятно, что человек заболеет гриппом при заданном наборе условий.

Ох, сколько вычислений.

Гауссовский наивный байесовский метод

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

Если мы хотим вычислить вероятность точки при условии y =c :

  • Сначала найдите строки, удовлетворяющие y=c
  • рассчитать среднее значение и стандартное отклонение для каждой функции или столбца для данного набора строк.
  • Для каждой точки данных в этом наборе строк подставьте значение x (которое является значением признака этой точки данных), среднее значение столбца и стандартное отклонение в приведенном ниже выражении.

  • Эти значения для каждого столбца затем умножаются, чтобы выяснить вероятность этой точки данных, применяя P(X|Y=c) = P(X₁, X₂, X₃,… Xₙ| Y = c) = P(X₁|Y = c)*P(X₂|Y = c)*P(X₃|Y = c)….*P(Xₙ|Y = c)

где X={X₁, X₂, X₃,… Xₙ} — признаки/независимые переменные.

Реализация набора данных Penguins

  • Импорт библиотек numpy, math и seaborn.
  • Я загрузил набор данных «пингвины», используя seaborn.load_dataset («пингвины»).
  • Для этого набора данных наша переменная ответа — «виды», а остальные столбцы — значения признаков.

Прежде чем реализовать наивный байесовский подход к набору данных, я проверил нулевые значения:

В некоторых строках 5 значений были нулевыми, а в некоторых строках только значения в столбце «пол» были нулевыми.

  • Сначала я узнал значение режима в столбце «пол» и заменил значения null в этом столбце на это значение. В моем случае режим был «Мужской».
  • Если некоторые из строк все еще имеют нулевые значения, я удалил их.

Я разделил набор данных в соотношении 80:20 для обучения и тестирования набора данных после преобразования набора данных в массив numpy (мне просто легче работать):

Функции

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

статистика_по_классу (х, у):

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

аргументы: набор x_train и набор y_train.

  • Сначала он обнаруживает все уникальные типы классов для нашей переменной ответа.
  • Инициализация «групп» словаря для каждого типа класса со всеми строками, у которых y = ‹Class_name›.
  • «статистика» хранит среднее значение и стандартное отклонение (оба для каждого столбца), индекс столбца (для идентификации столбцов с непрерывными значениями) и количество строк для каждого класса.
  • «category_prob» хранит логарифмические вероятности для столбцов, содержащих категориальные данные.

найти_статистика (х):

аргумент: x — это набор данных, соответствующая переменная ответа которого принадлежит определенному типу класса.

Он проверяет каждый столбец, содержат ли они данные строкового класса или нет. Если это не строковый тип, мы находим среднее значение и стандартное отклонение.

gaussian_prob(x_i,среднее,станд.):

находит вероятность, используя выражение распределения Гаусса для x_i, где x_i эквивалентно x[строка][столбец], а среднее значение и стандартное отклонение передаются для этого конкретного столбца.

find_category_prob(x,y,cls):

аргумент: здесь cls — это тип класса.

находит логарифмическое правдоподобие для всех предикторов при условии, что оно классифицируется по типу класса переменной ответа.

Опять же, мы проверяем тип данных столбца, если он содержит данные строкового класса, мы находим:

  • уникальные типы в этом столбце.
  • найдите строки в этом столбце, где y_train[row] = cls для каждого типа
  • разделите приведенное выше количество на общее количество этого типа в этом столбце.
  • Затем найдите его журнал и сохраните его в словаре вероятностей, где значением ключа является индекс столбца.

find_prob_for_class (статистика, test_row, category_prob = нет):

Эта функция находит апостериорные значения для P(Y=cls|X), где X — набор условий, представленных нашей тестовой строкой.

Мы вызываем gaussian_prob(), чтобы найти вероятности для непрерывных столбцов и найти их логарифмическое значение. Мы добавляем все эти значения журнала со значениями вероятности журнала, предоставленными словарем category_prob, и значением журнала вероятности нашего класса.

мы находим вероятность этого класса, разделив stats[cls][3] на total_rows в наборе данных.

прогнозировать (статистика, test_row, category_prob = None):

Он получает логарифмическое значение апостериорных значений из функции find_prob_for_class() и возвращает класс с максимальным апостериорным значением.

В любом случае, на этом наш блог заканчивается. Я надеюсь, что это даст вам небольшое преимущество в этой теме. Спасибо, что нашли время, чтобы прочитать это!!!

Доброго дня 😄!!!

P.S. Я весь внимание для всех исправлений и предложений. Не стесняйтесь указать, если я сделал что-то не так и как я могу сделать лучше.