La regresión logística (04-02) separa las clases con un hiperplano, pero se conforma con cualquier hiperplano que minimice la log-loss. Las máquinas de soporte vectorial (SVM, Support Vector Machines) hacen una pregunta más exigente: de todos los hiperplanos que separan a los clientes fieles de los que abandonan, ¿cuál lo hace con el máximo margen de seguridad? Y cuando ningún corte recto basta, despliegan su arma característica — el truco del kernel — para separar en un espacio de más dimensiones lo que en el original era inseparable. En esta lección construirás esa intuición geométrica paso a paso, entenderás qué papel juegan los vectores de soporte y el parámetro C, y aplicarás SVC al churn de MercaFresh — con los datos escalados, porque pocas familias de modelos son tan sensibles a la escala como esta.
Contenido
- El hiperplano de margen máximo
- Vectores de soporte: los clientes que definen la frontera
- Margen blando: el parámetro C
- El truco del kernel: separar lo inseparable
- Implementación con scikit-learn: SVC sobre el churn
- Sensibilidad a la escala y coste computacional
- Cuándo elegir (y cuándo no) una SVM
El hiperplano de margen máximo
Imagina el churn de MercaFresh con solo dos features: recencia_dias y tendencia. Los clientes fieles se agrupan abajo-derecha (recencia baja, tendencia alta); los que abandonan, arriba-izquierda. Entre ambos grupos caben infinitas rectas separadoras: una pegada a los fieles, otra pegada a los que se van, y todas las intermedias.
¿Cuál preferir? La intuición de la SVM: la recta que pasa lo más lejos posible de los puntos más cercanos de ambas clases. Esa distancia — de la frontera al punto más próximo de cada lado — es el margen, y maximizarlo es todo el objetivo del algoritmo.
¿Por qué el margen importa? Porque los datos futuros no caerán exactamente donde los de entrenamiento. Una frontera pegada a los clientes fieles clasificará mal al primer cliente fiel nuevo que caiga un milímetro más allá. La frontera de margen máximo deja la mayor "zona de amortiguación" posible a cada lado: es la apuesta geométrica por la generalización — el mismo objetivo que perseguíamos al vigilar el sobreajuste del árbol en 04-03, ahora incorporado al propio criterio de entrenamiento.
flowchart LR
subgraph "Frontera cualquiera"
A["Separa el train...<br/>pero roza una clase:<br/>fragil ante datos nuevos"]
end
subgraph "Frontera de margen maximo"
B["Equidistante de los puntos<br/>criticos de ambas clases:<br/>maxima holgura para generalizar"]
end
A -.->|"SVM elige"| B
Vectores de soporte: los clientes que definen la frontera
Aquí llega la propiedad más elegante del modelo. La posición del hiperplano de margen máximo depende solo de los puntos que tocan el margen — los más cercanos a la frontera. Esos puntos son los vectores de soporte (le dan nombre al algoritmo: literalmente sostienen la frontera).
Consecuencias prácticas:
- Los puntos lejanos no importan: el cliente fidelísimo con recencia de 2 días podría moverse o desaparecer y la frontera no cambiaría un ápice. Compara con la regresión lineal de 04-01, donde todos los puntos tiran de la recta (y un outlier la secuestra).
- El modelo es "disperso": de 800 clientes de entrenamiento, quizá solo 60 son vectores de soporte. El resto es irrelevante para predecir.
- Los vectores de soporte son los casos frontera del negocio: los clientes ambiguos, ni claramente fieles ni claramente perdidos. Inspeccionarlos (
modelo.support_vectors_) es mirar exactamente la zona gris donde la campaña de retención se juega su presupuesto.
Margen blando: el parámetro C
Con datos reales, casi nunca existe un hiperplano que separe las clases a la perfección: siempre hay algún cliente fiel con perfil de churner y viceversa (ruido, etiquetas dudosas, solapamiento genuino). Exigir separación perfecta —el margen duro— o es imposible o produce fronteras retorcidas por complacer excepciones.
La solución es el margen blando: permitir que algunos puntos violen el margen (o incluso caigan al lado equivocado), pagando una penalización por cada violación. El parámetro C regula el precio:
| C | Actitud | Frontera resultante | Riesgo |
|---|---|---|---|
| Pequeño (0.01) | Tolerante: margen ancho aunque haya errores dentro | Suave, general | Quedarse corto (underfitting) |
| Intermedio (1, el defecto) | Equilibrado | — | — |
| Grande (1000) | Estricto: casi ningún error tolerado | Ajustada a cada punto del train | Sobreajuste (06-05) |
C es el mando del compromiso entre ajustar el entrenamiento y mantener margen — la misma tensión que max_depth en el árbol, con otro disfraz. Encontrar su valor óptimo de forma sistemática (junto con los del kernel) es materia de 07-05; en esta lección lo moveremos a mano para ver su efecto.
El truco del kernel: separar lo inseparable
El caso que rompe todo lo anterior: datos donde ninguna recta funciona. Ejemplo clásico con sabor MercaFresh: los clientes que abandonan son los de gasto muy bajo (no les interesa) y los de gasto muy alto (los capta la competencia con ofertas agresivas), mientras los de gasto medio se quedan. En el eje del gasto, la clase "churn" ocupa los dos extremos: imposible separarla con un único corte.
La idea salvadora: añadir una dimensión. Si a cada cliente le añadimos la feature gasto² (distancia al centro), los churners de ambos extremos quedan arriba (gasto² grande) y los fieles abajo — y en ese espacio ampliado, un plano los separa limpiamente. La frontera lineal del espacio ampliado, vista desde el espacio original, es una curva.
El truco del kernel hace esto sin construir las features nuevas: las matemáticas de la SVM solo necesitan productos escalares entre puntos, y una función kernel calcula directamente "el producto escalar que tendrían los puntos en el espacio ampliado" sin visitarlo jamás. Es como obtener el beneficio de PolynomialFeatures (03-06) con infinitas features y coste de unas pocas.
| Kernel | kernel= |
Espacio implícito | Cuándo usarlo |
|---|---|---|---|
| Lineal | "linear" |
El original | Muchas features, pocas muestras; texto; primera prueba |
| Polinómico | "poly" |
Productos y potencias hasta grado d | Interacciones de orden conocido |
| RBF (gaussiano) | "rbf" (defecto) |
Dimensión infinita: similitud local tipo campana | Opción por defecto para problemas no lineales |
El kernel RBF merece una frase más: clasifica cada punto nuevo según su similitud (una campana gaussiana, pariente de la normal de 02-02) con los vectores de soporte — puede dibujar fronteras arbitrariamente curvas, incluso islas. Su parámetro gamma controla el alcance de esa similitud: gamma grande = campanas estrechas = frontera muy flexible (y proclive al sobreajuste); gamma pequeño = campanas anchas = frontera suave.
Implementación con scikit-learn: SVC sobre el churn
La SVM calcula distancias entre puntos, así que el escalado no es opcional: sin él, gasto_medio_pedido (decenas de euros) aplastaría a ratio_inactividad (0–1) en cualquier distancia. Recuperamos el preprocesador completo de 03-06 — con su RobustScaler — dentro del Pipeline, igual que en 04-02:
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
# 'preprocesador' es el ColumnTransformer de 03-06 (el mismo de 04-02),
# con imputacion, Yeo-Johnson, RobustScaler y codificacion categorica
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42)
svm_rbf = Pipeline([
("prep", preprocesador),
("modelo", SVC(kernel="rbf", C=1.0, gamma="scale", probability=True)),
])
svm_rbf.fit(X_train, y_train)
print(f"SVM RBF - accuracy en test: {svm_rbf.score(X_test, y_test):.2%}")
# Comparativa rapida de kernels y valores de C
for kernel in ["linear", "rbf"]:
for C in [0.1, 1, 100]:
m = Pipeline([("prep", preprocesador),
("modelo", SVC(kernel=kernel, C=C))])
m.fit(X_train, y_train)
print(f"kernel={kernel:6s} C={C:5} | "
f"train: {m.score(X_train, y_train):.2%} | "
f"test: {m.score(X_test, y_test):.2%} | "
f"vectores de soporte: {m.named_steps['modelo'].n_support_.sum()}")Claves de lectura:
gamma="scale": heurística de sklearn que adapta gamma a la varianza de los datos; buen punto de partida.probability=True: la SVM nativa devuelve distancias a la frontera, no probabilidades; esta opción añade una calibración interna (costosa) para poder usarpredict_probacomo en 04-02. Si solo necesitas la etiqueta o el ranking pordecision_function, omítela.- En la comparativa, observa el patrón: con C = 100, la accuracy de train sube y la de test suele bajar — el sobreajuste asomando —, mientras el número de vectores de soporte cae (margen estricto, menos puntos dentro). Con C = 0.1, margen ancho, más vectores de soporte y fronteras más suaves.
- Si
linearrinde ~igual querbf, quédate conlinear: más rápido, más interpretable (tiene coeficientes como 04-02) y menos hiperparámetros.
Sensibilidad a la escala y coste computacional
Dos advertencias de ingeniería antes de enamorarse del modelo:
Escala. La demostración de por qué el RobustScaler de 03-05 no es decorativo:
sin_escalar = Pipeline([
("prep", prep_arbol), # el preprocesador SIN escalado de 04-03
("modelo", SVC(kernel="rbf")),
])
sin_escalar.fit(X_train, y_train)
print(f"SVM sin escalar: {sin_escalar.score(X_test, y_test):.2%}")
# Tipicamente varios puntos peor que con el preprocesador completo:
# las distancias las domina la feature de mayor rango numericoCoste. El entrenamiento de una SVM con kernel crece aproximadamente entre O(n²) y O(n³) con el número de muestras — duplicar clientes multiplica el tiempo por 4-8. Órdenes de magnitud prácticos:
| Tamaño del dataset | SVM kernel RBF | Alternativa razonable |
|---|---|---|
| < 10 000 filas | Cómoda | — |
| 10 000 – 100 000 | Lenta; considerar LinearSVC |
Regresión logística, árboles |
| > 100 000 | Impracticable con kernel | Modelos lineales, ensembles (07-02) |
Además, predecir requiere comparar cada punto nuevo con todos los vectores de soporte: un modelo con miles de ellos es lento también en producción (08-02).
Cuándo elegir (y cuándo no) una SVM
| A favor de la SVM | En contra |
|---|---|
| Datasets pequeños o medianos con frontera compleja | Datasets grandes (coste de entrenamiento) |
| Muchas features y pocas muestras (kernel lineal brilla) | Necesidad de probabilidades bien calibradas de serie |
| Robustez frente a puntos lejanos (solo mandan los vectores de soporte) | Necesidad de interpretabilidad tipo reglas (usa 04-03) o coeficientes (04-02, kernel lineal aparte) |
| Máxima capacidad de separación con pocos datos | Muchísimo preprocesamiento obligatorio: escalar siempre |
Regla de oficio: en un problema tabular de tamaño MercaFresh (miles de clientes), prueba la logística como línea base, el árbol por interpretabilidad, y la SVM RBF cuando sospeches fronteras curvas que a los otros se les escapan. Si la SVM gana con claridad, suele señalar que hay estructura no lineal que también explotarán los ensembles (07-02, 07-03).
Errores Comunes y Consejos
- Entrenar sin escalar. El error número uno con SVM, y silencioso: el modelo entrena, predice y rinde mal sin avisar de por qué. El
Pipelinecon el preprocesador de 03-06 lo hace estructuralmente imposible. - Saltar directamente al kernel RBF con C y gamma al azar. Dos mandos sensibles a la vez producen desde underfitting severo hasta memorización total. Empieza con los defectos (
C=1, gamma="scale") y compara con el kernel lineal antes de sofisticarte; el ajuste fino sistemático llega en 07-05. - Usar
predict_probasin saber que cuesta.probability=Trueentrena una calibración adicional con validación interna: multiplica el tiempo de entrenamiento. Para rankings (a quién llamar primero) bastadecision_function, gratis. - Ignorar el desbalanceo de clases. Con 90% de clientes fieles, el margen óptimo puede sacrificar por completo a la clase minoritaria.
SVC(class_weight="balanced")reequilibra las penalizaciones; el diagnóstico fino, en 06-02. - Consejo: mira siempre
n_support_. Si la mayoría del train son vectores de soporte, el modelo está memorizando (C o gamma demasiado altos) o las clases se solapan de verdad — en ambos casos, es una alarma que ningún otro número te da tan barato.
Ejercicios
Ejercicio 1. Conceptual: en el dataset de churn hay un cliente fiel clarísimo (recencia 1 día, tendencia 2.0) muy lejos de la frontera, y un cliente ambiguo (recencia 55, tendencia 0.8) pegado a ella. ¿Cuál de los dos afecta a la frontera de la SVM si lo eliminas del entrenamiento? ¿Y en una regresión logística? Justifica.
Ejercicio 2. Con el Pipeline de la lección, entrena SVM RBF con gamma en [0.01, 0.1, 1, 10] (con C=1 fijo) y muestra accuracy en train y test para cada valor. Interpreta el patrón en términos de "alcance de la campana de similitud".
Ejercicio 3. MercaFresh abre línea mayorista y su dataset pasa de 5 000 a 2 000 000 de pedidos etiquetados. El equipo propone reentrenar la SVM RBF tal cual. Da dos razones para desaconsejarlo y dos alternativas concretas del curso.
Soluciones
Ejercicio 1
El cliente lejano no es vector de soporte: eliminarlo no cambia la frontera en absoluto — la SVM solo depende de los puntos que sostienen el margen. El ambiguo casi seguro sí lo es: quitarlo puede desplazar la frontera visiblemente. En la regresión logística ambos cuentan (todos los puntos aportan a la log-loss), aunque el lejano aporte un gradiente minúsculo: la frontera se movería, poco pero algo, en ambos casos. Moraleja: la SVM concentra su atención exactamente en la zona gris; la logística escucha a todos.
Ejercicio 2
for gamma in [0.01, 0.1, 1, 10]:
m = Pipeline([("prep", preprocesador),
("modelo", SVC(kernel="rbf", C=1, gamma=gamma))])
m.fit(X_train, y_train)
print(f"gamma={gamma:5} | train: {m.score(X_train, y_train):.2%}"
f" | test: {m.score(X_test, y_test):.2%}")Patrón esperado: con gamma = 0.01 las campanas son tan anchas que todo se parece a todo — frontera casi plana, rendimiento mediocre en ambos conjuntos (underfitting). Al subir gamma, test mejora hasta un máximo. Con gamma = 10 las campanas son tan estrechas que cada vector de soporte solo "ve" su vecindario inmediato: train se dispara hacia el 100% y test cae — el modelo ha dibujado una isla alrededor de cada cliente del train. Es la curva de 06-05 otra vez, ahora con gamma como mando de complejidad.
Ejercicio 3
Razones en contra: (1) coste de entrenamiento ~O(n²)-O(n³): pasar de 5 000 a 2 000 000 de filas multiplica el tiempo por cientos de miles — de minutos a meses; (2) el modelo resultante tendría una enormidad de vectores de soporte, haciendo también la predicción lenta y el modelo pesado en producción (08-03 tratará este mantenimiento). Alternativas del curso: regresión logística (04-02), que escala linealmente y da probabilidades; árboles (04-03) y sus ensembles (07-02, 07-03), que manejan millones de filas y no linealidad; o al menos LinearSVC, la variante lineal sin kernel, si se quiere conservar la filosofía de margen. Con muchísimos datos, los modelos simples alcanzan a los complejos: la ventaja de la SVM con kernel vive en el régimen de datos escasos.
Conclusión
Las SVM te han dado la tercera geometría del módulo: donde la logística ajusta un hiperplano probabilístico y el árbol trocea el espacio en rectángulos, la SVM busca el corte de máximo margen sostenido solo por los puntos frontera, tolera excepciones a un precio regulado por C, y — con el truco del kernel — separa en espacios implícitos lo que en el original era inseparable. A cambio exige respeto: escalado siempre, cautela con C y gamma, y conciencia de su coste cuando los datos crecen.
Fíjate en el ingrediente que el kernel RBF puso sobre la mesa: clasificar según la similitud con otros puntos. La próxima lección lleva esa idea a su expresión más pura y radical: un modelo sin entrenamiento, sin ecuación y sin frontera explícita, que clasifica cada cliente nuevo preguntando simplemente a sus vecinos más cercanos qué son ellos. Es K-Vecinos más cercanos, el algoritmo más intuitivo de todo el módulo.
Curso de Machine Learning
Módulo 1: Introducción al Machine Learning
- ¿Qué es el Machine Learning?
- Historia y evolución del Machine Learning
- Tipos de Machine Learning
- Aplicaciones del Machine Learning
- El flujo de trabajo de un proyecto de Machine Learning
Módulo 2: Fundamentos de Estadística y Probabilidad
- Conceptos básicos de estadística
- Distribuciones de probabilidad
- Correlación y covarianza
- Inferencia estadística
- Teorema de Bayes
Módulo 3: Preprocesamiento de Datos
- Limpieza de datos
- Manejo de datos faltantes
- Transformación de datos
- Codificación de variables categóricas
- Normalización y estandarización
- Ingeniería de características
Módulo 4: Algoritmos de Machine Learning Supervisado
- Regresión lineal
- Regresión logística
- Árboles de decisión
- Máquinas de soporte vectorial (SVM)
- K-Vecinos más cercanos (K-NN)
- Naive Bayes
- Redes neuronales
Módulo 5: Algoritmos de Machine Learning No Supervisado
- Clustering: K-means
- Clustering jerárquico
- Análisis de componentes principales (PCA)
- Análisis de agrupamiento DBSCAN
- Visualización de datos con t-SNE y UMAP
Módulo 6: Evaluación y Validación de Modelos
- División de datos: entrenamiento, validación y prueba
- Métricas de evaluación
- Validación cruzada
- Curva ROC y AUC
- Overfitting y underfitting
Módulo 7: Técnicas Avanzadas y Optimización
- Regularización: Ridge, Lasso y Elastic Net
- Ensemble Learning
- Gradient Boosting
- Redes neuronales profundas (Deep Learning)
- Optimización de hiperparámetros
Módulo 8: Implementación y Despliegue de Modelos
- Frameworks y bibliotecas populares
- Implementación de modelos en producción
- Mantenimiento y monitoreo de modelos
- Consideraciones éticas y de privacidad
Módulo 9: Proyectos Prácticos
- Proyecto 1: Predicción de precios de viviendas
- Proyecto 2: Clasificación de imágenes
- Proyecto 3: Análisis de sentimientos en redes sociales
- Proyecto 4: Detección de fraudes
- Proyecto 5: Segmentación de clientes
