que los modelos lineales pueden ser… bueno, rígidos. ¿Alguna vez has mirado un diagrama de dispersión y te has dado cuenta de que una línea recta simplemente no es suficiente? Todos hemos estado allí.
Los datos del mundo real siempre son un desafío. La mayoría de las veces, parece que la excepción es la regla. Los datos que obtienes en tu trabajo no se parecen en nada a esos hermosos conjuntos de datos lineales que utilizamos durante años de formación en la academia.
Por ejemplo, está viendo algo como “Demanda de energía frente a temperatura”. No es una línea; es una curva. Por lo general, nuestro primer instinto es recurrir a la regresión polinómica. ¡Pero eso es una trampa!
Si alguna vez has visto una curva modelo enloquecer en los bordes de tu gráfico, has sido testigo del “fenómeno Runge”. Los polinomios de alto grado son como un niño pequeño con un crayón, ya que son demasiado flexibles y no tienen disciplina.
Por eso les voy a mostrar esta opción llamada Splines. Son una buena solución: más flexibles que una línea, pero mucho más disciplinadas que un polinomio.
Los splines son funciones matemáticas definidas por polinomios y utilizadas para suavizar una curva.
En lugar de intentar ajustar una ecuación compleja a todo su conjunto de datos, divide los datos en segmentos en puntos llamados nudos. Cada segmento tiene su propio polinomio simple y todos están cosidos con tanta suavidad que ni siquiera se pueden ver las costuras.
El problema de los polinomios
Imaginemos que tenemos una tendencia no lineal y le aplicamos un polinomio x² o x³. Se ve bien localmente, pero luego miramos los bordes de los datos y la curva se desvía mucho. Según el fenómeno de Runge [2]los polinomios de alto grado tienen este problema en el que un punto de datos extraño en un extremo puede desequilibrar toda la curva en el otro extremo.
Por qué los splines son la opción “perfecta”
Los splines no intentan ajustar una ecuación gigante a todo. En cambio, dividen sus datos en segmentos utilizando puntos llamados nudos. Tenemos algunas ventajas al utilizar nudos.
Control local: lo que sucede en un segmento permanece en ese segmento. Debido a que estos fragmentos son locales, un punto de datos extraño en un extremo del gráfico no arruinará el ajuste en el otro extremo. Suavidad: Utilizan “B-splines” (splines de base) para garantizar que donde se unen los segmentos, la curva sea perfectamente suave. Estabilidad: a diferencia de los polinomios, no se vuelven locos en los límites.
De acuerdo. Basta de hablar, ahora implementemos esta solución.
Implementándolo con Scikit-Learn
SplineTransformer de Scikit-Learn es la opción ideal para esto. Convierte una única característica numérica en múltiples características básicas que un modelo lineal simple puede usar para aprender formas complejas y no lineales.
Importemos algunos módulos.
importar numpy como np importar matplotlib.pyplot como plt desde sklearn.preprocessing importar SplineTransformer desde sklearn.linear_model importar Ridge desde sklearn.pipeline importar make_pipeline desde sklearn.model_selection importar GridSearchCV
A continuación, creamos algunos datos oscilantes curvos.
# 1. Cree algunos datos sintéticos ‘movibles’ (por ejemplo, ventas estacionales) rng = np.random.RandomState(42) X = np.sort(rng.rand(100, 1) * 10, axis=0) y = np.sin(X).ravel() + rng.normal(0, 0.1, X.shape[0]) # Trazar los datos plt.figure(figsize=(12, 5)) plt.scatter(X, y, color=’gray’, alpha=0.5, label=’Data’) plt.legend() plt.title(“Data”) plt.show()
De acuerdo. Ahora crearemos una canalización que ejecute SplineTranformer con la configuración predeterminada, seguida de una regresión de crestas.
# 2. Construya una tubería: Splines + Modelo lineal # n_knots=5 (predeterminado) crea 4 segmentos; grado=3 lo convierte en un modelo spline cúbico = make_pipeline( SplineTransformer(n_knots=5, grado=3), Ridge(alpha=0.1) )
A continuación, ajustaremos el número de nudos de nuestro modelo. Usamos GridSearchCV para ejecutar múltiples versiones del modelo, probando diferentes recuentos de nudos hasta encontrar el que funciona mejor con nuestros datos.
# Ajustamos ‘n_knots’ para encontrar la mejor melodía param_grid = {‘splinetransformer__n_knots’: range(3, 12)} grid = GridSearchCV(model, param_grid, cv=5) grid.fit(X, y) print(f”Mejor recuento de nudos: {grid.best_params_[‘splinetransformer__n_knots’]}”) Mejor número de nudos: 8
Luego, volvemos a entrenar nuestro modelo spline con el mejor recuento de nudos, predecimos y trazamos los datos. Además, entendamos qué estamos haciendo aquí con este rápido desglose de los argumentos de la clase SplineTransformer:
n_knots: número de uniones de la curva. Cuanto más tienes, más flexible se vuelve la curva. grado: Esto define la “suavidad” de los segmentos. Se refiere al grado del polinomio utilizado entre nudos (1 es una línea; 2 es más suave; 3 es el valor predeterminado). Nudos: Éste le indica al modelo dónde colocar las uniones. Por ejemplo, uniforme separa la curva en espacios iguales, mientras que cuantil asigna más nudos donde los datos son más densos. Consejo: utilice “cuantil” si sus datos están agrupados. extrapolación: le dice al modelo qué debe hacer cuando encuentra datos fuera del rango que vio durante el entrenamiento. Consejo: utilice “periódico” para datos cíclicos, como el calendario o el reloj. include_bias: si se debe incluir una columna de “sesgo” (una columna de todos unos). Si utiliza un modelo LinearRegression o Ridge más adelante en su canalización, esos modelos generalmente tienen su propio fit_intercept=True, por lo que a menudo puede configurarlo en False para evitar la redundancia. # 2. Construya el modelo Spline optimizado = make_pipeline( SplineTransformer(n_knots=8, Degree=3, nudos= ‘uniform’, extrapolation=’constant’, include_bias=False), Ridge(alpha=0.1) ).fit(X, y) # 3. Prediga y visualice y_plot = model.predict(X) # Trazar plt.figure(figsize=(12, 5)) plt.scatter(X, y, color=’gris’, alpha=0.5, label=’Data’) plt.plot(X, y_plot, color=’teal’, linewidth=3, label=’Spline Model’) plt.plot(X, y_plot_10, color=’purple’, linewidth=2, label=’Ajuste polinómico (grado 20)’) plt.legend() plt.title(“Splines: flexibles pero disciplinados”) plt.show()
Aquí está el resultado. Con splines tenemos mejor control y un modelo más suave, evitando el problema en los extremos.
Estamos comparando un modelo polinomial de grado=20 con el modelo spline. Se puede argumentar que los grados inferiores pueden modelar mucho mejor estos datos, y serían correctos. He probado hasta el grado 13 y encaja bien con este conjunto de datos.
Sin embargo, ese es exactamente el objetivo de este artículo. Cuando el modelo no se ajusta demasiado bien a los datos y necesitamos seguir aumentando el grado del polinomio, ciertamente caeremos en el problema de los bordes salvajes.
Aplicaciones de la vida real
¿Dónde usarías esto realmente en los negocios?
Ciclos de series de tiempo: utilice extrapolación=’periodic’ para funciones como “hora del día” o “mes del año”. Garantiza que el modelo sepa que las 11:59 p. m. están justo al lado de las 0:01 a. m. Con este argumento, le decimos al SplineTransformer que el final de nuestro ciclo (hora 23) debe terminar y encontrarse con el comienzo (hora 0). De este modo, el spline garantiza que la pendiente y el valor al final del día coincidan perfectamente con el inicio del día siguiente. Dosis-Respuesta en Medicina: Modelado de cómo un fármaco afecta a un paciente. La mayoría de los medicamentos siguen una curva no lineal donde el beneficio eventualmente se estabiliza (saturación) o, peor aún, se convierte en toxicidad. Los splines son el “estándar de oro” aquí porque pueden mapear estos cambios biológicos complejos sin forzar los datos a adoptar una forma rígida. Ingresos versus experiencia: el salario a menudo crece rápidamente desde el principio y luego se estabiliza; Las splines capturan esta “curva” perfectamente.
Antes de ir
Hemos cubierto mucho aquí, desde por qué los polinomios pueden ser una elección “salvaje” hasta cómo los splines periódicos resuelven la brecha de medianoche. Aquí hay un resumen rápido para guardar en su bolsillo trasero:
La regla de oro: utilice splines cuando una línea recta sea demasiado simple, pero un polinomio de alto grado comience a oscilar y a sobreajustarse. Los nudos son clave: Los nudos son las “uniones” de su modelo. Encontrar el número correcto a través de GridSearchCV es la diferencia entre una curva suave y un desastre irregular. Energía periódica: para cualquier característica que tenga ciclos (horas, días, meses), use extrapolación = ‘periódica’. Garantiza que el modelo comprenda que el final del ciclo vuelve perfectamente al principio. Ingeniería de funciones > Modelos complejos: a menudo, una simple regresión Ridge combinada con SplineTransformer superará a un modelo complejo de “caja negra” y, al mismo tiempo, será mucho más fácil de explicar a su jefe.
Si te gustó este contenido, encuentra más sobre mi trabajo y mis contactos en mi sitio web.
https://gustavorsantos.me
Repositorio GitHub
Aquí está el código completo de este ejercicio y un par de extras.
https://github.com/gurezende/Studying/blob/master/Python/sklearn/SplineTransformer.ipynb
Referencias
[1. SplineTransformer Documentation] https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.SplineTransformer.html
[2. Runge’s Phenomenon] https://en.wikipedia.org/wiki/Runge%27s_phenomenon
[3. Make Pipeline Docs] https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html