Mesa:
Introdução
Naive Bayes é um algoritmo de classificação de aprendizado de máquina baseado no teorema de Bayes. É muito eficiente principalmente quando se trata de dados textuais como: Análise de Sentimentos, detecção de Spam e classificação de textos.
Este algoritmo é chamado de “Ingênuo” devido à suposição de que todas as variáveis do conjunto de dados são independentes, o que nem sempre é o caso.
Antes de prosseguir na explicação de como o Naive bayes funciona, vamos ter certeza de que entendemos o seguinte:
Probabilidade Condicional
O algoritmo Naive Bayes é baseado no teorema de Bayes que se baseia na probabilidade condicional: é a probabilidade de ocorrência de um evento A dado que um evento B já ocorreu.
Exemplo:
Vamos ter dois potes que contêm bolas coloridas:
-
O frasco 1 tem 3 bolas azuis, 2 bolas vermelhas e 4 bolas verdes.
-
O frasco 2 tem 1 bola azul, 4 bolas vermelhas e 3 bolas verdes.
Queremos calcular a probabilidade de selecionar aleatoriamente uma bola azul de um dos potes
Não é outro senão a soma das probabilidades de selecionar uma bola azul do Jar1 ou Jar2.
Agora, queremos calcular a probabilidade de selecionar uma bola azul dado que selecionamos Jar1:
Finalmente, queremos calcular a probabilidade de selecionar Jar1, dado que extraímos uma bola azul. Aqui usamos o Teorema de Bayes que é expresso da seguinte forma:
Classificação Naive Bayes
No classificador Naive Bayes, queremos encontrar a classe que maximiza a probabilidade condicional dado o vetor de entrada X; assim, Naive Bayes pode ser formulado da seguinte forma:
Com o uso do Teorema de Bayes, a função torna-se:
Nesta formulação, é fácil calcular P(Ci) que nada mais é do que a probabilidade da classe Ci, e é fácil calcular P(x) que é a probabilidade de ocorrência do evento x.
O que é difícil de calcular é P(x|Ci); a probabilidade do evento x dada a classe Ci. Para simplificar ainda mais, precisamos assumir que todas as variáveis de entrada são independentes; assim, podemos escrever:
E é por causa dessa suposição que chamamos esse classificador de “Ingênuo”, porque nem sempre podemos garantir a independência das variáveis de entrada. O classificador Naive Bayes torna-se:
Na verdade, podemos simplificar ainda mais esta formulação eliminando P(x), porque é o mesmo para todas as classes:
Agora, vamos dar uma olhada em um exemplo:
| Tempo | Tempo | Dia da semana | Jantar |
| ------- | -------- | --------------- | ------ |
| Limpar | Noite | Fim de semana | Cozinheiros |
| Nublado | Noite | Dia da semana | Encomendas |
| Chuvoso | Noite | Dia da semana | Encomendas |
| Chuvoso | Meio-dia | Dia da semana | Encomendas |
| Nublado | Meio-dia | Fim de semana | Cozinheiros |
| Limpar | Noite | Fim de semana | Cozinheiros |
| Nevado | Noite | Fim de semana | Encomendas |
| Limpar | Noite | Dia da semana | Cozinheiros |
| Limpar | Meia-noite | Fim de semana | Encomendas |
Aqui, temos um pequeno conjunto de dados que contém 3 variáveis de entrada: Clima, Hora e Dia da semana, e uma variável de destino: “Jantar” que indica se uma pessoa cozinha ou pede seu jantar. Gostaríamos de encontrar a classe da entrada x={Clear, Evening, Weekend}:
Precisamos calcular a probabilidade condicional para a classe “Cozinheiros” e a classe “Pedidos” dada a entrada x={Clear, Evening, Weekend}. A classe prevista é aquela que tem a maior probabilidade condicional.
Começamos calculando a probabilidade condicional da classe “Cozinheiros”:
Agora calculamos cada probabilidade condicional por conta própria:
A probabilidade de tempo=”Limpo” dado que a classe é “Cozinheiros” é o número de linhas com tempo “Limpo” e classe “Cozinheiros” sobre o número total de linhas com classe “Cozinheiros”
O mesmo vale para as outras probabilidades condicionais:
Agora para a probabilidade P(Cooks) é o número de linhas com classe “Cooks” sobre o número total de linhas:
Agora calculamos o produto dessas probabilidades:
Isso foi para a turma “Cozinheiros”, agora precisamos fazer o mesmo para a turma “Pedidos”:
Calculamos as probabilidades individuais:
E finalmente calculamos o produto das probabilidades:
Por fim, pegamos a classe com maior probabilidade que é a classe “Cozinheiros”:
Vantagens e limitações deste algoritmo
Vantagens:
-
É um classificador muito rápido.
-
É fácil de implementar.
-
Não há fase de treinamento, mas é apenas inferência.
-
Não requer muitos dados para fazer inferências.
Limitações:
- Naive Bayes assume que as variáveis de entrada são independentes, o que nem sempre é verdade.
- Naive Bayes sofre do problema da frequência zero: é quando atribui probabilidade zero a uma variável de entrada. Isso zerará toda a probabilidade condicional P(C|x). Um truque para evitar isso é usar uma frequência mínima de 1 (em vez de 0) para todas as variáveis.
Exercício
Aqui está o dataframe do mesmo conjunto de dados que vimos no exemplo.
Sua tarefa é implementar você mesmo o Naive Bayes usando python:
import pandas as pd
dataset = pd.DataFrame()
dataset['Weather'] = ['Clear', 'Cloudy', 'Rainy', 'Rainy', 'Cloudy', 'Clear', 'Snowy', 'Clear', 'Clear']
dataset['Time'] = ['Evening', 'Night', 'Night', 'Midday', 'Midday', 'Night', 'Evening', 'Night', 'Midnight']
dataset['Day'] = ['Weekend', 'Weekday', 'Weekday', 'Weekday', 'Weekend', 'Weekend', 'Weekend', 'Weekday', 'Weekend']
dataset['Class'] = ['Cooks', 'Orders', 'Orders', 'Orders', 'Cooks', 'Cooks', 'Orders', 'Cooks', 'Orders']
def naive_bayes(weather, time, day):
# res_dict = {class1: probability of class 1, class1: probability of class 1
return res_dict
Solução
def naive_bayes(x_weather, x_time, x_day):
TARGET = 'Dinner' # The name of the target variable
CLASSES = list(dataset['Dinner'].unique()) # The classes of the target variable
len_dataset = len(dataset) # The length of the dataset
res_dict = {} # res_dict = {class1:probability1, ..., class_n:probability_n}
# for each class of the target classes, we calculate the it's conditional probability
for class_name in CLASSES:
# the number of lines that belong to the class "class_name"
len_c = len(dataset[ (dataset[TARGET] == class_name) ])
# the number of lines that belong to the class "class_name" and have weather="x_weather"
n_weather = len(dataset[ (dataset[TARGET] == class_name) & (dataset['Weather'] == x_weather) ])
# the number of lines that belong to the class "class_name" and have time="x_time"
n_time = len(dataset[ (dataset[TARGET] == class_name) & (dataset['Time'] == x_time) ])
# the number of lines that belong to the class "class_name" and have day="x_day"
n_day = len(dataset[ (dataset[TARGET] == class_name) & (dataset['Day'] == x_day) ])
# We calculate the conditional probability:
# P(class|x) = P(weather|class) x P(time|class) x P(day|class) x P(class)
p = (n_weather / len_c) * (n_time / len_c) * (n_day / len_c) * (len_c / len_dataset) res_dict[class_name] = p
return res_dict