Redes Neuronales para Regresión con Scikit-Learn
MLPRegressor: Implementación de Redes Neuronales
MLPRegressor es la implementación de redes neuronales multicapa (Multi-Layer Perceptron) en scikit-learn específicamente diseñada para problemas de regresión. Esta clase utiliza algoritmos de optimización como LBFGS o descenso de gradiente estocástico para minimizar el error cuadrático.
Características Principales
Arquitectura Automática para Regresión:
- Capa de salida: Automáticamente configura una neurona única para predecir valores continuos
- Función de activación de salida: Utiliza la función “identity” (lineal) por defecto, definida como f(x) = x
- Rango de salida: (-∞, +∞), permitiendo predicciones en cualquier rango real
Diferencias con Clasificación:
- Clasificación binaria: 1 neurona + sigmoid
- Clasificación multiclase: n neuronas + softmax
- Regresión: 1 neurona + identity (lineal)
Ejemplo de Implementación Básica
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score
# Configuración completa de MLPRegressor para regresión
mlp_regressor = MLPRegressor(
hidden_layer_sizes=(100, 50, 25), # Arquitectura: 3 capas ocultas
activation='relu', # Función de activación en capas ocultas
solver='adam', # Optimizador
alpha=0.001, # Regularización L2
learning_rate_init=0.001, # Tasa de aprendizaje inicial
max_iter=2000, # Máximo número de iteraciones
random_state=42, # Semilla para reproducibilidad
early_stopping=True, # Parada temprana
validation_fraction=0.1, # Fracción para validación
n_iter_no_change=10 # Iteraciones sin mejora para parar
)
# IMPORTANTE: Para regresión, la capa de salida usa automáticamente:
# - Una neurona (para valores continuos)
# - Función de activación 'identity' (lineal: f(x) = x)
# Entrenar el modelo
mlp_regressor.fit(X_train, y_train)
# Hacer predicciones
y_pred = mlp_regressor.predict(X_test)
# Evaluar el modelo
r2 = r2_score(y_test, y_pred)
rmse = sqrt(mean_squared_error(y_test, y_pred))
La función de activación lineal es especialmente importante en regresión porque no restringe el rango de valores de salida, permitiendo que el modelo prediga cualquier valor real. Esto contrasta con funciones como sigmoid (rango 0-1) o tanh (rango -1 a 1) que limitarían las predicciones.
Pipelines Avanzados
TransformedTargetRegressor: Transformaciones en Variable Objetivo
TransformedTargetRegressor es una herramienta meta-estimador que permite aplicar transformaciones no lineales a la variable objetivo (y) antes del entrenamiento y automáticamente aplica la transformación inversa durante las predicciones. Es especialmente útil cuando la variable objetivo tiene distribuciones sesgadas o no normales.
Funcionamiento:
- Durante entrenamiento: regressor.fit(X, func(y))
- Durante predicción: inverse_func(regressor.predict(X))
from sklearn.compose import TransformedTargetRegressor
import numpy as np
# Crear el regresor con transformación del target
transformed_regressor = TransformedTargetRegressor(
regressor=MLPRegressor(hidden_layer_sizes=(100, 50), random_state=42),
func=np.log, # Función de transformación
inverse_func=np.exp # Función inversa para las predicciones
)
# Entrenar el modelo (automáticamente aplica log(y))
transformed_regressor.fit(X_train, y_train)
# Hacer predicciones (automáticamente aplica exp() para volver a escala original)
predictions = transformed_regressor.predict(X_test)
Casos de Uso Comunes:
- Variables objetivo con distribución exponencial → transformación logarítmica
- Variables objetivo muy sesgadas → transformaciones de Box-Cox
- Variables objetivo con valores muy grandes → normalización/escalado
ColumnTransformer: Manejo Diferenciado por Tipo de Variable
ColumnTransformer permite aplicar diferentes transformaciones a diferentes subconjuntos de características en paralelo. Esta herramienta es fundamental cuando se trabaja con datasets que contienen tipos de variables mixtos (numéricas y categóricas).
Ventajas Clave:
- Transformación selectiva: Aplica transformaciones específicas a subconjuntos de columnas
- Integración con pipelines: Se integra perfectamente con Pipeline de scikit-learn
- Organización del código: Encapsula toda la lógica de preprocesamiento
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.neural_network import MLPRegressor
from sklearn.pipeline import Pipeline
# Definir transformaciones por tipo de variable
preprocessor = ColumnTransformer(
transformers=[
# Variables numéricas: escalado estándar
('num', StandardScaler(), ['edad', 'salario', 'experiencia']),
# Variables categóricas: codificación one-hot
('cat', OneHotEncoder(drop='first', sparse=False), ['ciudad', 'educacion'])
],
remainder='drop' # Eliminar columnas no especificadas
)
# Pipeline completo
pipeline = Pipeline([
('preprocessor', preprocessor),
('regressor', MLPRegressor(
hidden_layer_sizes=(100, 50),
activation='relu',
random_state=42,
max_iter=2000
))
])
# Entrenar el pipeline
pipeline.fit(X_train, y_train)
# El pipeline maneja automáticamente:
# 1. Transformación de datos de entrenamiento
# 2. Entrenamiento del modelo
# 3. Transformación de datos nuevos durante predicción
predictions = pipeline.predict(X_test)
Parámetro remainder:
'passthrough': Mantiene columnas no transformadas en la salida'drop': Elimina columnas no especificadas- Transformer personalizado: Aplica transformación específica a columnas restantes
Consideraciones para Producción
Consistencia en Transformaciones entre Entrenamiento y Predicción
Uno de los problemas más críticos en producción es la inconsistencia entre las transformaciones aplicadas durante el entrenamiento y las aplicadas durante la predicción. Esta inconsistencia puede causar predicciones completamente erróneas.
Problema Común:
- Entrenar con ciertas transformaciones en desarrollo
- Aplicar transformaciones diferentes o en orden distinto en producción
- Resultado: Predicciones sistemáticamente incorrectas
Solución: Serialización de Pipelines Completos
import pickle
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.neural_network import MLPRegressor
# 1. ENTRENAR PIPELINE COMPLETO
pipeline_prod = Pipeline([
('preprocessor', ColumnTransformer([
('num', StandardScaler(), ['feature1', 'feature2']),
('cat', OneHotEncoder(drop='first'), ['category'])
])),
('model', MLPRegressor(hidden_layer_sizes=(100, 50)))
])
# Entrenar
pipeline_prod.fit(X_train, y_train)
# 2. GUARDAR PIPELINE COMPLETO
with open('model_pipeline.pkl', 'wb') as f:
pickle.dump(pipeline_prod, f)
# 3. CARGAR EN PRODUCCIÓN
with open('model_pipeline.pkl', 'rb') as f:
loaded_pipeline = pickle.load(f)
# 4. USAR EN PRODUCCIÓN (mismo preprocesamiento automático)
predictions = loaded_pipeline.predict(new_data)
Validación de Disponibilidad de Variables en Tiempo Real
La validación de datos de entrada es crucial para garantizar predicciones confiables en producción. Los datos pueden tener problemas de calidad, valores faltantes o estar fuera de los rangos esperados.
# EJEMPLO: VALIDACIÓN DE DATOS EN TIEMPO REAL
import pandas as pd
import numpy as np
from typing import Dict, Any, List
class ProductionValidator:
def __init__(self, training_stats: Dict):
self.training_stats = training_stats
def validate_input(self, input_data: pd.DataFrame) -> Dict[str, Any]:
"""
Valida datos de entrada antes de hacer predicciones
"""
validation_results = {
'is_valid': True,
'errors': [],
'warnings': []
}
# 1. Verificar columnas requeridas
required_columns = self.training_stats['required_columns']
missing_columns = set(required_columns) - set(input_data.columns)
if missing_columns:
validation_results['is_valid'] = False
validation_results['errors'].append(
f"Columnas faltantes: {missing_columns}"
)
# 2. Verificar tipos de datos
for col, expected_type in self.training_stats['column_types'].items():
if col in input_data.columns:
if input_data[col].dtype != expected_type:
validation_results['warnings'].append(
f"Tipo de datos inesperado en {col}: {input_data[col].dtype} vs {expected_type}"
)
# 3. Verificar rangos de variables numéricas
for col in self.training_stats['numeric_ranges']:
if col in input_data.columns:
col_min, col_max = self.training_stats['numeric_ranges'][col]
out_of_range = (
(input_data[col] < col_min) |
(input_data[col] > col_max)
).sum()
if out_of_range > 0:
validation_results['warnings'].append(
f"{out_of_range} valores fuera de rango en {col}"
)
return validation_results
Data Drift: Cambios en Distribuciones de Datos
Data drift se refiere a cambios en las distribuciones estadísticas de los datos después de que el modelo ha sido desplegado. Este fenómeno puede degradar significativamente el rendimiento del modelo con el tiempo.
Tipos de Data Drift:
- Covariate Drift (Deriva de Covariables):
- Cambio en la distribución de variables de entrada P(X)
- Ejemplo: La edad promedio de usuarios cambia de 30 a 45 años
- Concept Drift (Deriva de Concepto):
- Cambio en la relación entre características y objetivo P(y|X)
- Ejemplo: Las mismas características predicen diferentes precios debido a cambios en el mercado
- Prior Probability Drift (Deriva de Probabilidad Previa):
- Cambio en la distribución del objetivo P(y)
- Ejemplo: Precios promedio aumentan por inflación
Métodos de Detección:
La literatura identifica aproximadamente 40 enfoques únicos de detección de deriva, agrupados en cinco clases: métricas basadas en distancia, métricas basadas en error, enfoques compuestos, métodos adaptativos y métodos basados en aprendizaje activo.
# EJEMPLO: DETECCIÓN DE DATA DRIFT
import numpy as np
from scipy import stats
from sklearn.metrics import r2_score
class DataDriftDetector:
def __init__(self, reference_data):
self.reference_data = reference_data
self.reference_stats = {
'mean': np.mean(reference_data, axis=0),
'std': np.std(reference_data, axis=0)
}
def detect_drift(self, new_data, alpha=0.05):
"""
Detecta drift usando test Kolmogorov-Smirnov
"""
drift_detected = {}
for i in range(new_data.shape):
# Test K-S para cada característica
statistic, p_value = stats.ks_2samp(
self.reference_data[:, i],
new_data[:, i]
)
drift_detected[f'feature_{i}'] = {
'drift': p_value < alpha,
'p_value': p_value,
'statistic': statistic
}
return drift_detected
def performance_drift(self, model, X_new, y_new, baseline_r2):
"""
Detecta drift basado en degradación de rendimiento
"""
current_r2 = r2_score(y_new, model.predict(X_new))
performance_drop = baseline_r2 - current_r2
return {
'performance_drift': performance_drop > 0.1, # Umbral del 10%
'baseline_r2': baseline_r2,
'current_r2': current_r2,
'drop': performance_drop
}
# USAR EL DETECTOR
detector = DataDriftDetector(X_train)
drift_results = detector.detect_drift(X_production)
Impacto del Data Drift:
- Reducción de precisión: Los modelos se vuelven menos confiables
- Problemas de cumplimiento: En industrias reguladas como finanzas o salud
- Pérdida de confianza: Los usuarios pueden perder confianza en el sistema
- Aumento de costos: Predicciones erróneas pueden llevar a decisiones comerciales pobres
Estrategias de Manejo:
- Reentrenamiento periódico: Actualizar modelos con datos recientes
- Monitoreo continuo: Implementar alertas automáticas cuando se detecta deriva
- Modelos adaptativos: Usar enfoques que se adapten automáticamente a cambios
- Líneas base establecidas: Mantener estadísticas de referencia del entrenamiento
Mejores Prácticas para Producción
Diseño del Modelo:
- Comenzar con arquitecturas simples y aumentar complejidad gradualmente
- Implementar early stopping para evitar sobreajuste
- Usar regularización apropiada (parámetro alpha)
- Validación cruzada para selección de hiperparámetros
Preprocesamiento Robusto:
- Siempre usar pipelines para garantizar consistencia
- Manejar valores faltantes explícitamente
- Escalar variables numéricas apropiadamente
- Codificar variables categóricas de manera consistente
Monitoreo y Mantenimiento:
- Implementar detección automática de data drift
- Mantener logging detallado para debugging
- Establecer alertas cuando el rendimiento decae
- Capacidad de rollback para modelos problemáticos
La implementación exitosa de redes neuronales para regresión en producción requiere una comprensión profunda de estos componentes y una estrategia integral que aborde tanto los aspectos técnicos como operacionales del despliegue de modelos de machine learning.
Hi :)
Matemáticas
Vectores
Álgebra Lineal
Geometría Analítica
Producto Punto
Espacios Vectoriales
Ortogonalidad
Normalización
Funciones
Álgebra
Composición de Funciones
Función Inversa
Combinación de Funciones
Transformaciones Gráficas
Aplicaciones Económicas
Interés Compuesto
Proporcionalidad
R
Data
Machine Learning
Aprendizaje Supervisado
Inteligencia Artificial
Clasificación
Regresión
Deep Learning