O algoritmo “Naive Bayes” é um classificador probabilístico muito utilizado em machine learning. Baseado no “Teorema de Bayes”, o modelo foi criado por um matemático inglês, e também ministro presibiteriano, chamado Thomas Bayes (1701 – 1761) para tentar provar a existência de Deus.
Hoje é também utilizado na área de Aprendizado de Máquina (Machine Learning) para categorizar textos com base na frequência das palavras usadas.
Entre as possibilidades de aplicações está a classificação de um e-mail como SPAM ou Não-SPAM e a identificação de um assunto com base em seu conteúdo.
Ele recebe o nome de “naive” (ingênuo) porque desconsidera a correlação entre as variáveis (features). Ou seja, se determinada fruta é rotulada como “Limão”, caso ela também seja descrita como “Verde” e “Redonda”, o algoritmo não vai levar em consideração a correlação entre esses fatores. Isso porque trata cada um de forma independente.
🆕 Este artigo foi revisado e atualizado em maio de 2022!
Aplicação do Naive Bayes
Frequentemente aplicado em processamento de linguagem natural e diagnósticos médicos, o método pode ser usado quando os atributos que descrevem as instâncias forem condicionalmente independentes. Ou seja, o teorema de Bayes trata sobre probabilidade condicional. Isto é, qual a probabilidade de o evento A ocorrer, dado o evento B.
Um problema simples que exemplifica bem o teorema é o cálculo de probabilidades em cima de diagnóstico de doenças.
Imagine que estamos trabalhando no diagnóstico de uma nova doença. Após realizar testes, coletas e análises com 100 pessoas distintas, descobrimos que 20 pessoas possuíam a doença (20%) e 80 pessoas estavam saudáveis (80%).
De todas as pessoas que possuíam a doença, 90% receberam Positivo no teste. Já 30% das pessoas que não possuíam a doença também receberam o teste positivo.
Vamos para a tabulação dos dados:
100 pessoas realizaram o teste.
20% das pessoas que realizaram o teste possuíam a doença.
90% das pessoas que possuíam a doença, receberam positivo no teste.
30% das pessoas que não possuíam a doença, receberam positivo.
A partir destes dados, surge o problema: se uma nova pessoa realizar o teste e receber um resultado positivo, qual a probabilidade dela realmente possuir a doença?
Essa probabilidade a posteriori é resolvida pelo Naive Bayes. Para isso, é preciso multiplicar a probabilidade a priori (possuir a doença) pela probabilidade de “receber um resultado positivo, dado que tem a doença”.
Com esses dados, também podemos calcular a probabilidade a posteriori da negação (não possuir a doença, dado que recebeu um resultado positivo).
Ou seja:
P(doença|positivo) = 20% * 90%
P(doença|positivo) = 0,2 * 0,9
P(doença|positivo) = 0,18
P(não doença|positivo) = 80% * 30%
P(não doença|positivo) = 0,8 * 0,3
P(não doença|positivo) = 0,24
Finalizado o cálculo inicial, é preciso normalizar os dados, para que a soma das duas probabilidades resulte 100% ou 1. Para gerar os dados normalizados dividimos o resultado pela soma das duas probabilidades.
Exemplo:
P(doença|positivo) = 0,18/(0,18+0,24) = 0,4285
P(não doença|positivo) = 0,24/(0,18+0,24) = 0,5714
0,4285 + 0,5714 = 0,9999.. (ou aproximadamente 1)
Implementação em Python
Aqui nós implementamos Naive Bayes Gaussiano utilizando o banco de dados do Titanic Disaster, disponível no Github. Usaremos as classes sala, sexo, idade, número de irmãos / cônjuges, número de pais / filhos, tarifa de passageiro e informações do porto de embarque.
import pandas as pd import numpy as np import matplotlib.pyplot as plt import time from sklearn.model_selection import train_test_split from sklearn.naive_bayes import GaussianNB, BernoulliNB, MultinomialNB # Importing dataset data = pd.read_csv("data/train.csv") # Convert categorical variable to numeric data["Sex_cleaned"]=np.where(data["Sex"]=="male",0,1) data["Embarked_cleaned"]=np.where(data["Embarked"]=="S",0, np.where(data["Embarked"]=="C",1, np.where(data["Embarked"]=="Q",2,3) ) ) # Cleaning dataset of NaN data=data[[ "Survived", "Pclass", "Sex_cleaned", "Age", "SibSp", "Parch", "Fare", "Embarked_cleaned" ]].dropna(axis=0, how='any') # Split dataset in training and test datasets X_train, X_test = train_test_split(data, test_size=0.5, random_state=int(time.time()))
# Instantiate the classifier gnb = GaussianNB() used_features =[ "Pclass", "Sex_cleaned", "Age", "SibSp", "Parch", "Fare", "Embarked_cleaned" ] # Train classifier gnb.fit( X_train[used_features].values, X_train["Survived"] ) y_pred = gnb.predict(X_test[used_features]) # Print results print("Number of mislabeled points out of a total {} points : {}, performance {:05.2f}%" .format( X_test.shape[0], (X_test["Survived"] != y_pred).sum(), 100*(1-(X_test["Survived"] != y_pred).sum()/X_test.shape[0]) ))
Resultado: Número de pontos errados de um total de 357 pontos: 68, desempenho 80.95%
Aqui calculamos as probabilidades P (Sobrevivência = 1) e P (Sobrevivência = 0):
mean_survival=np.mean(X_train["Survived"]) mean_not_survival=1-mean_survival print("Survival prob = {:03.2f}%, Not survival prob = {:03.2f}%" .format(100*mean_survival,100*mean_not_survival))
Resultado: Probabilidade de Sobrevivência = 39,50% e Probabilidade de Não Sobrevivência = 60,50%
Após isso poderíamos calcular a probabilidade de sobrevivência a partir de qualquer outra variável condicional.
Conclusão
A resolução de problemas relacionados a texto é muito bem resolvida com a utilização do Naive Bayes. Classificação de textos, filtragem de SPAM e análise de sentimento em redes sociais são algumas das muitas aplicações para o algoritmo.
Além disso, o algoritmo é muito robusto para previsões em tempo real, ainda mais por precisar de poucos dados para realizar a classificação. Entretanto, caso haja necessidade de correlacionar fatores, o Naive Bayes tende a falhar na predição.
Curtiu o post? Então compartilha nas redes sociais e continue acompanhando os próximos artigos sobre ciência de dados!