Наивный байесовский вывод и три общие модели

машинное обучение

Наивный байесовский алгоритм — это простой алгоритм классификации, который хорошо известен своим классическим вариантом использования: классификация текста (например, фильтрация спама). Многие учебники начинаются с этих случаев, и эта статья не будет их повторять, а сосредоточится на теоретическом выводе (на самом деле это очень просто, не пугайтесь «теории»), трех распространенных моделях и их кодовой реализации (Python) .

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

Кроме того, весь код в этой статье можноПолучите это с моего github


1. Теоретическая основа Наивного Байеса

Алгоритм наивного Байеса — это метод классификации, основанный на теореме Байеса и предположении о независимости признаков от условий.

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

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

Что первоеУсловная возможность.

P(A|B) представляет собой вероятность того, что событие A произойдет при условии, что произошло событие B, которая называется условной вероятностью события A при наступлении события B. Его основная формула решения: Р(А|В)=Р(АВ) Р(В)

Теорема Байеса основана на условной вероятности, и P(B|A) вычисляется как P(A|B):

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

Кстати, знаменатель P(A) в приведенной выше формуле можно разложить на:

P (A)=∑ n i =1 P (B i )P (A| B i )


1.2 Допущение независимости характерных условий

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

Учитывая набор обучающих данных (X, Y), где каждая выборка x включает n-мерные признаки, т.е. x =(x 1 ,x 2 ,x 3 ,...,x n ) набор меток класса содержит k категорий, а именно у = (у 1 , у 2 ,..., у к ) .

Если сейчас есть новый образец x, как мы оцениваем его категорию? С вероятностной точки зрения вопрос состоит в том, при данном x какой класс имеет наибольшую вероятность оказаться в нем. Тогда проблема превращается в решение Наибольшее из P (y 1 | x), P (y 2 | x),..., P (y k | x), то есть выход с наибольшей апостериорной вероятностью: a rg max y k P (y k | x)

Тот Как решить P(yk|x)? Ответ — теорема Байеса:

P (y k | x)=P (x| y k )P (y k )P (x)

В соответствии с формулой полной вероятности знаменатель в приведенной выше формуле может быть дополнительно разложен:

P (y k | x) = P (x | y k )P (y k )∑ k P (x | y k )P (y k )【Формула 1】

Отдохни здесь две минуты

Независимо от знаменателя, числитель P(yk) — это априорная вероятность, которую можно легко вычислить по обучающей выборке.

а условная вероятность P (x| y k )=P(x 1 ,x 2 ,...,x n | y k ) , его шкала параметров является экспоненциальной, предполагая i-е характеристики измерения Количество возможных значений для x i равно S i , количество значений категории равно k, тогда количество параметров равно: k ∏ n я =1 S я

Это явно невыполнимо.В ответ на эту проблему алгоритм наивного Байеса делает предположение о независимости условного распределения вероятностей., с точки зрения непрофессионала, это означает принятие характеристик каждого измерения x 1 , x 2 ,..., x n не зависят друг от друга.Исходя из этого предположения, условная вероятность может быть преобразована в:

P (x| y k )=P(x 1 ,x 2 ,...,x n | y k )=∏ n i =1 P (x i | y k )[Формула 2]

Таким образом, размер параметра уменьшается до ∑ п я =1 S я к

Вышеприведенное является характерным допущением условной независимости, сделанным для условной вероятности. P (y k ) и условные вероятности Все проблемы решения P (x| y k ) решены, так что можем ли мы решить желаемую апостериорную вероятность? Р (у к | х)?

Подумайте здесь две минуты

Ответ положительный. Мы продолжаем выше о Для вывода P (y k | x) подставьте [формулу 2] в [формулу 1], чтобы получить:

P (y k | x) = P (y k )∏ n i =1 P (x i | y k ) ∑ k P (y k )∏ n i =1 P (x i | y k )

Тогда наивный байесовский классификатор может быть выражен как:

f (x)=arg max y k P(y k | x)=a rg max y k P (y k )∏ n i =1 P (x i | y k ) ∑ k P (y k )∏ n i =1 P (x i | y k )

потому что для всех y k , значение знаменателя в приведенной выше формуле такое же (почему? Это легко понять, когда вы заметите полный символ плюса), поэтому вы можете игнорировать часть знаменателя, и наивный байесовский классификатор, наконец, выражается как:

f (x)=arg max P(y k )∏ n i =1 P (x i | y k )

о Р(ук) , Есть три общие модели для решения P (xi | y k ).


2. Три общие модели и программные реализации

2.1 Полиномиальная модель

Когда признаки дискретны, используется полиномиальная модель. Полиномиальные модели используются для расчета априорных вероятностей. P (y k ) и условные вероятности P (x i | y k ), сделает некоторыесглаживание, конкретная формула:

P (y k )=N y k +α N +kα

N — общее количество образцов, k — общее количество категорий, N y k – категория для количество выборок y k, α — сглаженное значение.

P (x i | y k )=N y k ,x i +α N y k +n α

— количество выборок с категорией , n — размерность признака, а — количество выборок со значением i-го признака измерения в выборке с категорией, которое является сглаженным значением.

В то время это называлось сглаживанием Лапласа, в то время это называлось сглаживанием Лидстоуна, и оно вообще не было сглажено.

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


2.1.1 Пример

Имеются следующие обучающие данные, 15 выборок, 2-мерные признаки, 2 категории - 1, 1. По тестовому образцу определите его категорию.

这里写图片描述

Ответ таков:

Используя полиномиальную модель, пусть

  • Вычислить априорную вероятность

这里写图片描述

  • Расчет различных условных вероятностей

这里写图片描述

  • Для заданного вычислить:

这里写图片描述

Отсюда можно определить, что y=-1.


2.1.2 Программная реализация (на основе Python, Numpy)

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

Мой код написан в соответствии с этой идеей. Определите класс MultinomialNB с двумя основными методами: fit(X,y) и predict(X). Метод подгонки на самом деле является обучением.Когда вызывается метод подгонки, задача заключается в построении таблицы поиска. Метод предсказания — это предсказание, и когда вызывается метод предсказания, задача состоит в том, чтобы вычислить все апостериорные вероятности и найти наибольшую из них. Кроме того, в конструкторе __init__() класса допускается задавать значение, а также задавать значение априорной вероятности. Конкретный код выглядит следующим образом:

"""
Created on 2015/09/06

@author: wepon (http://2hwp.com)

API Reference: http://scikit-learn.org/stable/modules/naive_bayes.html#naive-bayes
"""
import numpy as np

class MultinomialNB(object):
        """
        Naive Bayes classifier for multinomial models
        The multinomial Naive Bayes classifier is suitable for classification with
        discrete features

        Parameters
        ----------
        alpha : float, optional (default=1.0)
                Setting alpha = 0 for no smoothing
        Setting 0 < alpha < 1 is called Lidstone smoothing
        Setting alpha = 1 is called Laplace smoothing 
        fit_prior : boolean
                Whether to learn class prior probabilities or not.
                If false, a uniform prior will be used.
        class_prior : array-like, size (n_classes,)
                Prior probabilities of the classes. If specified the priors are not
                adjusted according to the data.

        Attributes
        ----------
        fit(X,y):
                X and y are array-like, represent features and labels.
                call fit() method to train Naive Bayes classifier.

        predict(X):


    """

    def __init__(self,alpha=1.0,fit_prior=True,class_prior=None):
        self.alpha = alpha
        self.fit_prior = fit_prior
        self.class_prior = class_prior
        self.classes = None
        self.conditional_prob = None


    def _calculate_feature_prob(self,feature):
        values = np.unique(feature)
        total_num = float(len(feature))
        value_prob = {}
        for v in values:
            value_prob[v] = (( np.sum(np.equal(feature,v)) + self.alpha ) /( total_num + len(values)*self.alpha))
        return value_prob


    def fit(self,X,y):
        #TODO: check X,y

        self.classes = np.unique(y)
        #calculate class prior probabilities: P(y=ck)
        if self.class_prior == None:
            class_num = len(self.classes)
            if not self.fit_prior:
                self.class_prior = [1.0/class_num for _ in range(class_num)]  #uniform prior
            else:
                self.class_prior = []
                sample_num = float(len(y))
                for c in self.classes:
                    c_num = np.sum(np.equal(y,c))
                    self.class_prior.append((c_num+self.alpha)/(sample_num+class_num*self.alpha))

        #calculate Conditional Probability: P( xj | y=ck )
        self.conditional_prob = {}  # like { c0:{ x0:{ value0:0.2, value1:0.8 }, x1:{} }, c1:{...} }
        for c in self.classes:
            self.conditional_prob[c] = {}
            for i in range(len(X[0])):  #for each feature
                feature = X[np.equal(y,c)][:,i]
                self.conditional_prob[c][i] = self._calculate_feature_prob(feature)
        return self


    #given values_prob {value0:0.2,value1:0.1,value3:0.3,.. } and target_value
    #return the probability of target_value
    def _get_xj_prob(self,values_prob,target_value):
        return values_prob[target_value]

    #predict a single sample based on (class_prior,conditional_prob)
    def _predict_single_sample(self,x):
        label = -1
        max_posterior_prob = 0

        #for each category, calculate its posterior probability: class_prior * conditional_prob
        for c_index in range(len(self.classes)):
            current_class_prior = self.class_prior[c_index]
            current_conditional_prob = 1.0
            feature_prob = self.conditional_prob[self.classes[c_index]]
            j = 0
            for feature_i in feature_prob.keys():
                current_conditional_prob *= self._get_xj_prob(feature_prob[feature_i],x[j])
                j += 1

            #compare posterior probability and update max_posterior_prob, label
            if current_class_prior * current_conditional_prob > max_posterior_prob:
                max_posterior_prob = current_class_prior * current_conditional_prob
                label = self.classes[c_index]
        return label

    #predict samples (also single sample)           
    def predict(self,X):
        #TODO1:check and raise NoFitError 
        #ToDO2:check X
        if X.ndim == 1:
                return self._predict_single_sample(X)
        else:
                #classify each sample   
                labels = []
                for i in range(X.shape[0]):
                        label = self._predict_single_sample(X[i])
                        labels.append(label)
                return labels

Давайте воспользуемся приведенным выше примером, чтобы проверить это.Обратите внимание, что S, M и L заменены на 4, 5 и 6 здесь:

import numpy as np
X = np.array([
                      [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3],
                      [4,5,5,4,4,4,5,5,6,6,6,5,5,6,6]
             ])
X = X.T
y = np.array([-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1])

nb = MultinomialNB(alpha=1.0,fit_prior=True)
nb.fit(X,y)
print nb.predict(np.array([2,4]))#输出-1

2.2 Модель Гаусса

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


2.2.1 Для иллюстрации на примере:

пример гендерной классификации
из вики

Ниже приведен набор статистических данных о физических характеристиках человека.

Пол Высота (футы) Вес в фунтах) Футы (дюймы)
мужчина 6 180 12
мужчина 5.92 190 11
мужчина 5.58 170 12
мужчина 5.92 165 10
Женский 5 100 6
Женский 5.5 150 8
Женский 5.42 130 7
Женский 5.75 150 9

Известно, что рост человека 6 футов, вес 130 фунтов и длина ноги 8 дюймов. Это мужчина или женщина? Рассчитайте значение следующей формулы в соответствии с наивным байесовским классификатором.

P(身高|性别) x P(体重|性别) x P(脚掌|性别) x P(性别)

Трудность здесь заключается в том, что, поскольку рост, вес и подошвы ног являются непрерывными переменными, вероятность не может быть рассчитана с использованием дискретных переменных. А поскольку выборка слишком мала, ее нельзя разделить на интервальный расчет. что делать?
В это время можно предположить, что рост, вес и подошвы мужчин и женщин распределены нормально, а среднее значение и дисперсия вычисляются по выборкам, то есть получается функция плотности нормального распределения. С помощью функции плотности вы можете подставить значение и вычислить значение функции плотности в определенной точке.
Например, рост мужчин нормально распределяется со средним значением 5,855 и дисперсией 0,035. Итак, относительное значение вероятности того, что рост человека 6 футов, равно 1,5789 (больше 1 не имеет значения, поскольку это значение функции плотности, которая используется только для отражения относительной вероятности каждого значения ).

这里写图片描述

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

   P(身高=6|男) x P(体重=130|男) x P(脚掌=8|男) x P(男) 
    = 6.1984 x e-9
  P(身高=6|女) x P(体重=130|女) x P(脚掌=8|女) x P(女) 
    = 5.3778 x e-4

Можно видеть, что вероятность женщин почти в 10 000 раз выше, чем у мужчин, поэтому человек считается женщиной.

  • Суммировать

Модель Гаусса предполагает, что каждое измерение имеет распределение Гаусса (нормальное распределение):

Представляет среднее значение признака i-го измерения в выборке класса .
Представляет дисперсию признака i-го измерения в выборке класса .


2.2.2 Программная реализация

Единственная разница между моделью Гаусса и полиномиальной моделью заключается в вычислении Модель Гаусса предполагает, что признаки каждого измерения подчиняются нормальному распределению, и что необходимо вычислить, так это среднее значение и дисперсию признаков каждого измерения. Итак, мы определяем класс GaussianNB, наследуемся от MultinomialNB и перегружаем соответствующие методы. код показывает, как показано ниже:

#GaussianNB differ from MultinomialNB in these two method:
# _calculate_feature_prob, _get_xj_prob
class GaussianNB(MultinomialNB):
        """
        GaussianNB inherit from MultinomialNB,so it has self.alpha
        and self.fit() use alpha to calculate class_prior
        However,GaussianNB should calculate class_prior without alpha.
        Anyway,it make no big different

        """
        #calculate mean(mu) and standard deviation(sigma) of the given feature
        def _calculate_feature_prob(self,feature):
                mu = np.mean(feature)
                sigma = np.std(feature)
                return (mu,sigma)

        #the probability density for the Gaussian distribution 
        def _prob_gaussian(self,mu,sigma,x):
                return ( 1.0/(sigma * np.sqrt(2 * np.pi)) *
                        np.exp( - (x - mu)**2 / (2 * sigma**2)) )

        #given mu and sigma , return Gaussian distribution probability for target_value
        def _get_xj_prob(self,mu_sigma,target_value):
                return self._prob_gaussian(mu_sigma[0],mu_sigma[1],target_value)


2.3 Модель Бернулли

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

В модели Бернулли условная вероятность рассчитывается как:

Когда собственное значение равно 1,;

Когда собственное значение равно 0,;


2.3.1 Программная реализация

Модель Бернулли и полиномиальная модель согласуются друг с другом. БернуллиNB должен определить метод бинаризации больше, чем MultinomialNB.Этот метод будет принимать порог и бинаризировать входные функции (1, 0). Конечно, MultinomialNB также можно использовать напрямую, но входные признаки должны быть предварительно бинаризованы. Я не хочу писать это здесь, и программная реализация предоставляется читателю.


3 ссылки


Пожалуйста, укажите источник для перепечатки, спасибо:blog.CSDN.net/U012162613/…