Clasificador de spam Naive Bayes

Implementa un clasificador de spam chino simple con la fórmula de probabilidad condicional más básica, sin usar sklearn.

Al completar este caso, comprenderás:Teorema de Bayes + suposición de «independencia entre palabras» = un clasificador de texto funcional.


Introducción desde la vida cotidiana

Filtro de spam del correo

Tu correo electrónico recibe 100 mensajes al día. ¿Cómo lograr que el programa determine automáticamente si un correo nuevo es spam? El método del programa: calcular, a partir de los correos históricos, la probabilidad de que aparezcan palabras como «gratis» o «premio» en el spam, y de que aparezcan «reunión» o «proyecto» en los correos normales.

Cuando llega un correo nuevo, calcula: la probabilidad de que estas palabras aparezcan simultáneamente bajo la hipótesis de spam frente a la hipótesis de correo normal. Se asigna a la hipótesis con mayor probabilidad.


Comprensión intuitiva

La simplificación clave de Naive Bayes — «suposición ingenua»: supone que la aparición o no de cada palabra es independiente. Aunque esta suposición no se cumple en la realidad («gratis» y «premio» suelen aparecer juntas), su efecto práctico es sorprendentemente bueno.

TécnicaProcedimientoProblema que resuelve
Probabilidad logarítmicaUsar log para convertir multiplicaciones en sumasMultiplicar muchos decimales puede convertirse en 0 (subdesbordamiento numérico)
Suavizado de LaplaceSumar 1 al conteo de cada palabra en lugar de +0Las palabras no vistas en el conjunto de entrenamiento hacen que la probabilidad sea 0

Práctica con Python

Ejemplo

from collections import defaultdict
import math

# Datos de entrenamiento (8 SMS chinos etiquetados)
train_data = [
    (Gana premios gratis, haz clic ahora., "spam"),
    (Felicidades, ha ganado, reclame efectivo y descuentos., "spam"),
    (Oferta por tiempo limitado, haga clic en el enlace, gratis., "spam"),
    (Préstamo a bajo interés, solicite ahora efectivo., "spam"),
    (Reunión programada mañana por la mañana para discutir., "ham"),
    (Informe de progreso del proyecto y acta de la reunión., "ham"),
    (Cena de fin de semana, organizada para que todos participen., "ham"),
    (Informe de análisis de datos del proyecto completado, "ham"),
]

# Contar la frecuencia de palabras de cada categoría
class_word_counts = defaultdict(lambda: defaultdict(int))
class_doc_counts = defaultdict(int)
vocab = set()

for text, label in train_data:
    class_doc_counts[label] += 1
    for word in text.split():
        class_word_counts[label][word] += 1
        vocab.add(word)

vocab_size = len(vocab)
total_docs = len(train_data)

# Clasificación de Naive Bayes (log-probabilidades + suavizado de Laplace)
def predict(text, alpha=1.0):
    words = text.split()
    scores = {}
    for label in class_doc_counts:
        log_prob = math.log(class_doc_counts[label] / total_docs)
        total_words = sum(class_word_counts[label].values())
        for word in words:
            word_count = class_word_counts[label][word]
            word_prob = (word_count + alpha) / (total_words + alpha * vocab_size)
            log_prob += math.log(word_prob)
        scores[label] = log_prob
    return max(scores, key=scores.get), scores

# Prueba
test_emails = [
    "Reclama gratis premios en efectivo",
    "Reunión de mañana: informe de proyecto",
    "Haz clic en el enlace de oferta por tiempo limitado",
    El fin de semana todos discutimos el informe juntos,
]

print(Resultado de clasificación Naive Bayes de EJEMPLO:\n")
for email in test_emails:
    label, scores = predict(email)
    print(f"  {email!r:28s} -> 【{label}】")
EJEMPLO 朴素贝叶斯分类结果:

  '免费 领取 现金 奖品'          -> 【spam】
  '明天 会议 项目 汇报'           -> 【ham】
  '限时 点击 优惠 链接'           -> 【spam】
  '周末 大家 一起 讨论 报告'       -> 【ham】

Escenarios de aplicación en IA

EscenarioDescripción
Clasificación de textoFiltro de spam, clasificación de noticias, análisis de sentimiento: Naive Bayes es el baseline clásico
Modelado de temas en documentosBase matemática de LDA (Latent Dirichlet Allocation)
Detección de anomalíasCalcular la probabilidad de que una nueva muestra pertenezca a la «distribución normal»; si es demasiado baja, se clasifica como anómala.
Otras extensiones