Naive Bayes

Vamos criar a classe Naive Bayes para representar o nosso algoritmo. O método init representa o construtor, inicializando as variáveis do nosso modelo. O modelo gerado é formado basicamente pela frequência das palavras, que em nosso caso, representa os possíveis valores de cada feature e label.

  • O defaultdict é utilizado para inicializar nosso dicionário com valores default, no caso 0 (int), para chaves que tentamos acessar e ainda não foram adicionadas.

In [1]:
from collections import defaultdict
from functools import reduce
import math

class NaiveBayes:

    def __init__(self):

        self.freqFeature = defaultdict(int)
        self.freqLabel = defaultdict(int)

        # condFreqFeature[label][feature]
        self.condFreqFeature = defaultdict(lambda: defaultdict(int))

Modelo

Como o modelo é representado basicamente pela frequência das palavras, precisamos categorizar os possíveis valores das features. Após esse processo, fazemos a contagem.

  • countFrequencies: faz a contagem que cada valor de feature e label aparecem em todo o dataset de treino, independentemente.
  • countCondFrequencies: faz a contagem que cada valor de feature aparece para cada possível label.

In [2]:
def countFrequencies(self)

In [3]:
def countCondFrequencies(self)

Treino

Vamos treinar o nosso modelos. O que deve ser composto na função de treino?


In [4]:
def train(self, dataSet_x, dataSet_y)

Classificação

Com o modelos em mãos, agora podemos classificar nosso dataset. Abaixo, segue algumas dicas para tratarmos melhor os dados em nossa função.


In [6]:
def predict(self, dataSet_x):

        # Correcao de Laplace
        # P( f | l) = (freq( f | l ) + laplace*) / ( freq(l)** + qnt(distinct(f))*** )
        #
        # * -> laplace smoothing: add 1
        # ** -> Frequencia com que o valor de label aparece
        # *** -> Quantidade de features distintas
        #

        # Devido a possibilidade de underflow de pontos flutuantes, eh interessante fazer
        # P(x1|l)*P(x2|l) ... -> Log(P(x1|l)) + Log(P(x2|l)) ...

Pré-processamento

Abaixo uma função de suporte para a leitura do nosso dataset. Em seguida, um processo de separação dos dados entre dados de treino e teste.


In [7]:
import random

# Car dataset
# Attribute Information:
#
# Class Values:
#
# unacc, acc, good, vgood
#
# Attributes:
#
# buying: vhigh, high, med, low.
# maint: vhigh, high, med, low.
# doors: 2, 3, 4, 5more.
# persons: 2, 4, more.
# lug_boot: small, med, big.
# safety: low, med, high.

#Retur dataset
def readFile(path):
    rawDataset = open(path, 'r')


    suffix = ['_buy', '_maint', '_doors', '_pers', '_lug', '_safety', '_class']

    dataset = []

    rawDataset.seek(0)
    for line in rawDataset:
    	l = line.split(',')
        l[-1] = l[-1].replace("\n", "")
        newTuple = map(lambda (x,y): x+y, zip( l , suffix))
        dataset.append( newTuple )

    return dataset

In [ ]:
def main():

    preparedDataset = readFile('carData.txt')

    random.shuffle(preparedDataset)

    dataset = []
    #Features
    dataset.append([])
    #Label
    dataset.append([])

    for t in preparedDataset:
        dataset[0].append(t[:-1])
        dataset[1].append(t[-1])


    dataSet_x = dataset[0]
    dataSet_y = dataset[1]

    nTuples = len(dataSet_x)

    nToTrain = int(nTuples * 0.7)

    dataSet_x_train = dataSet_x[:nToTrain]
    dataSet_y_train = dataSet_y[:nToTrain]

    dataSet_x_test = dataSet_x[nToTrain:]
    dataSet_y_test = dataSet_y[nToTrain:]

    naive = NaiveBayes()

    naive.train(dataSet_x_train, dataSet_y_train)

    accuracy = 0.0

    results = naive.predict(dataSet_x_test)

    for index, r in enumerate(results):
        yPredicted = max(r, key=r.get)
        y = dataSet_y_test[index]
        
        if(y == yPredicted):
            accuracy += 1.0

    print accuracy / len(dataSet_y_test)

main()

Atividade

Perceba que separamos os dados de treino e teste em 70% e 30%, respectivamente. Qual tal testarmos nosso classificador com o processo de Cross-validation? Implemente a abordagem K-fold, com k = 10.

Referência: https://www.cs.cmu.edu/~schneide/tut5/node42.html


In [ ]: