Implemente um classifacor Naive Bayes para o problema de predizer a qualidade de um carro. Para este fim, utilizaremos um conjunto de dados referente a qualidade de carros, disponível no UCI. Este dataset de carros possui as seguintes features e classe:
Attributos
Classes
In [394]:
# Importa as bibliotecas
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
In [22]:
# Carrega os dados
cols = ['buying','maint','doors','persons','lug_book','safety','class']
carset = pd.read_csv('carData.csv',names=cols)
carset.head()
Out[22]:
In [23]:
carset.info()
Sem valores faltantes. Amém!
In [388]:
# Implementa o classificador naive bayes
class naive_classifier(object):
def _init_(self):
self.priors = {}
self.lh_probs = {}
self.train = None
def calc_prior_probs(self):
train = self.train
classes = train['class'].unique()
priors = {}
for class_ in classes:
priors[class_] = len(train[train['class'] == class_])/len(train)
self.priors = priors
def calc_likelihood_probs(self):
train = self.train
columns = carset.drop(['class'],axis=1).columns
classes = carset['class'].unique()
lh_probs = {}
for column in columns:
for class_ in classes:
for cat in carset[column].unique():
cat_prior_prob = sum(train[column]==cat)/len(train)
conditional_prob = sum((train['class']==class_) & (train[column]==cat))/sum(train['class']==class_)
if not conditional_prob: conditional_prob = 0.001
lh_probs[column,cat,class_] = conditional_prob/cat_prior_prob
self.lh_probs = lh_probs
def fit(self,train):
self.train = train
self.calc_prior_probs()
self.calc_likelihood_probs()
def predict(self,xtest):
columns = self.train.drop(['class'],axis=1).columns
classes = self.train['class'].unique()
predictions = []
for i in xtest.index:
posterior_prob = {}
x = xtest.loc[i]
for class_ in classes:
posterior_prob[class_] = 1
for column in columns:
#cat_prior = sum(self.train[column]==x[column])
posterior_prob[class_] *= self.lh_probs[column,x[column],class_]
posterior_prob[class_] *= self.priors[class_]
predictions.append(max(posterior_prob,key=posterior_prob.get))
return predictions
In [389]:
# Instancia um classificador e realiza predições para os dados de teste
msk = np.random.rand(len(carset))<=0.8
xtrain = carset[msk]
xtest = carset[~msk]
ytrain = xtrain['class']
ytest = xtest['class']
naive = naive_classifier()
naive.fit(xtrain)
pred = naive.predict(xtest)
acc_my_nb = np.mean(pred==ytest)*100
In [390]:
from sklearn.metrics import classification_report
my_nv_report = classification_report(ytest,pred)
Crie uma versão de sua implementação usando as funções disponíveis na biblioteca SciKitLearn para o Naive Bayes (veja aqui)
In [391]:
# Transform as features categóricas em numéricas
from sklearn.naive_bayes import GaussianNB
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(xtrain['class'])
ytrain = le.transform(xtrain['class'])
ytest = le.transform(xtest['class'])
xtrain =pd.get_dummies(xtrain.drop(['class'],axis=1))
xtest = pd.get_dummies(xtest.drop(['class'],axis=1))
xtrain.head()
Out[391]:
In [392]:
# Aplica o classifcador Naive Bayes (sklearn)
nb = GaussianNB()
nb.fit(xtrain,ytrain)
pred = nb.predict(xtest)
acc_sk_nb = np.mean(pred == ytest)*100
In [393]:
print('Acurária do classificador(from scratch):',acc_my_nb)
print('Acurária do classificador(sklearn version):',acc_sk_nb)
A acurácia obtida pelos classifcadores foram bem próximas. Como na versão do sklearn as features precisam ser numéricas, a tranformação categórica-numérica pode afetar o desempenho.
In [ ]: