Implementación del Clasificador Naive Bayes en Python

Clasificado en Informática

Escrito el en español con un tamaño de 6,49 KB

Ejercicio 1: Cálculo de la Probabilidad a Priori

La función prob_prior calcula la probabilidad a priori de una clase específica dentro de un conjunto de etiquetas y.

def prob_prior(clase, y):
    return y.count(clase) / len(y)

Ejercicio 2: Cálculo de la Probabilidad Condicionada

En este apartado se define la probabilidad condicionada de que un atributo tome un valor determinado, dada una clase específica, utilizando el conjunto de datos X e y.

def prob_cond(atributo, valor, clase, X, y):
    n_clase = 0
    n_clase_y_valor = 0
    for ejemplo, c in zip(X, y):
        if c == clase:
            n_clase += 1
            if ejemplo[atributo] == valor:
                n_clase_y_valor += 1
    return n_clase_y_valor / n_clase

Ejercicio 3: Cálculo Global de Probabilidades

Esta función, calcula_probs, permite obtener de forma masiva las probabilidades a priori y las probabilidades condicionadas para todos los atributos y valores posibles del dataset.

def calcula_probs(X, y):
    n_total = len(y)
    n_atributos = len(X[0])   # número de columnas/atributos (todas las listas de X miden igual)
    clases = set(y)
    valores_posibles = []
    for atributo in range(n_atributos):
        valores_columna = set(ejemplo[atributo] for ejemplo in X)
        valores_posibles.append(valores_columna)
    
    n_clase = {c: 0 for c in clases}
    n_atrib_valor_clase = {}
    
    for atributo in range(n_atributos):
        for valor in valores_posibles[atributo]:
            for c in clases:
                n_atrib_valor_clase[(atributo, valor, c)] = 0
                
    for ejemplo, c in zip(X, y):
        n_clase[c] += 1
        for atributo in range(n_atributos):
            valor = ejemplo[atributo]
            n_atrib_valor_clase[(atributo, valor, c)] += 1
            
    prob_priori = {c: n / n_total for c, n in n_clase.items()}
    prob_condicionada = {
        clave: n / n_clase[clave[2]]
        for clave, n in n_atrib_valor_clase.items()
    }
    return prob_priori, prob_condicionada

Ejercicio 4: Predicción y Clase Naive Bayes

Función de Predicción Individual

Implementación de la predicción basada en el modelo Naive Bayes (NB) para un nuevo ejemplo.

def predicción_NB(probprior, probcond, ejemplo):
    mejor_clase = None
    mejor_prob = -1
    for clase in probprior:
        prob = probprior[clase]
        for atributo, valor in enumerate(ejemplo):
            prob *= probcond[(atributo, valor, clase)]
        if prob > mejor_prob:
            mejor_prob = prob
            mejor_clase = clase
    return mejor_clase

Clase NaiveBayes con Suavizado de Laplace

A continuación, se presenta la estructura de la clase NaiveBayes, que incorpora el parámetro k para aplicar el suavizado de Laplace durante el entrenamiento.

class NaiveBayes():
    def __init__(self, k=1):
        self.k = k
        self.probprior = None
        self.probcond = None
        self.valores_posibles = None
        self.n_clase = None

    def entrena(self, X, y):
        n_total = len(y)
        n_atributos = len(X[0])
        clases = set(y)
        valores_posibles = []
        
        for atributo in range(n_atributos):
            valores_columna = set(ejemplo[atributo] for ejemplo in X)
            valores_posibles.append(valores_columna)
            
        n_clase = {c: 0 for c in clases}
        n_atrib_valor_clase = {}
        
        for atributo in range(n_atributos):
            for valor in valores_posibles[atributo]:
                for c in clases:
                    n_atrib_valor_clase[(atributo, valor, c)] = 0
                    
        for ejemplo, c in zip(X, y):
            n_clase[c] += 1
            for atributo in range(n_atributos):
                valor = ejemplo[atributo]
                n_atrib_valor_clase[(atributo, valor, c)] += 1
                
        probprior = {c: n / n_total for c, n in n_clase.items()}
        probcond = {}
        
        for (atributo, valor, c), n in n_atrib_valor_clase.items():
            num_valores_atributo = len(valores_posibles[atributo])
            probcond[(atributo, valor, c)] = (
                (n + self.k) / (n_clase[c] + self.k * num_valores_atributo)
            )
            
        self.probprior = probprior
        self.probcond = probcond
        self.valores_posibles = valores_posibles
        self.n_clase = n_clase

    def predicción(self, ejemplo):
        mejor_clase = None
        mejor_prob = -1
        for clase in self.probprior:
            prob = self.probprior[clase]
            for atributo, valor in enumerate(ejemplo):
                prob *= self.probcond[(atributo, valor, clase)]
            if prob > mejor_prob:
                mejor_prob = prob
                mejor_clase = clase
        return mejor_clase

Ejercicio 5: División del Conjunto de Datos

Función para realizar el split o división entre el conjunto de entrenamiento y el conjunto de prueba (test), garantizando la aleatoriedad mediante random.shuffle.

def divide_entrenamiento_prueba(X, y, prop_test=0.2):
    n = len(X)
    indices = list(range(n))
    random.shuffle(indices)
    n_test = int(n * prop_test)
    indices_test = indices[:n_test]
    indices_entr = indices[n_test:]
    
    X_entr = [X[i] for i in indices_entr]
    y_entr = [y[i] for i in indices_entr]
    X_test = [X[i] for i in indices_test]
    y_test = [y[i] for i in indices_test]
    
    return X_entr, y_entr, X_test, y_test

Ejercicio 7: Evaluación del Rendimiento

Finalmente, se define una función para medir el rendimiento del clasificador, calculando el porcentaje de aciertos sobre un conjunto de datos de validación.

def rendimiento(clasificador, X, y):
    aciertos = 0
    for ejemplo, clase_real in zip(X, y):
        prediccion = clasificador.predicción(ejemplo)
        if prediccion == clase_real:
            aciertos += 1
    return aciertos / len(y)

Entradas relacionadas: