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écnica | Procedimiento | Problema que resuelve |
|---|---|---|
| Probabilidad logarítmica | Usar log para convertir multiplicaciones en sumas | Multiplicar muchos decimales puede convertirse en 0 (subdesbordamiento numérico) |
| Suavizado de Laplace | Sumar 1 al conteo de cada palabra en lugar de +0 | Las palabras no vistas en el conjunto de entrenamiento hacen que la probabilidad sea 0 |
Práctica con Python
Ejemplo
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
| Escenario | Descripción |
|---|---|
| Clasificación de texto | Filtro de spam, clasificación de noticias, análisis de sentimiento: Naive Bayes es el baseline clásico |
| Modelado de temas en documentos | Base matemática de LDA (Latent Dirichlet Allocation) |
| Detección de anomalías | Calcular la probabilidad de que una nueva muestra pertenezca a la «distribución normal»; si es demasiado baja, se clasifica como anómala. |