ScikitLearn
Tutorial ScikitLearn: Regresión lineal
Scikit-Learn y regresiones lineales: guía para implementar regresión lineal simple, múltiple, polinómica y regularizada. Optimiza tus modelos con preprocesado e interpretabilidad.
Aprende ScikitLearn GRATIS y certifícateIntroducción teórica a la regresión lineal para regresión
La regresión lineal es uno de los modelos más fundamentales y ampliamente utilizados en el aprendizaje automático y la estadística para predecir valores continuos. Su objetivo principal es establecer una relación lineal entre una o múltiples variables independientes (predictoras) y una variable dependiente (respuesta), asumiendo que esta relación puede aproximarse mediante una línea recta en el caso unidimensional, o un hiperplano en dimensiones superiores.
Matemáticamente, el modelo de regresión lineal se expresa como:
$$
y = β_0 + β_1 x_1 + β_2 x_2 + \dots + β_n x_n + ϵ
$$
Donde:
- $( y )$ es la variable dependiente.
- $( x_i )$ son las variables independientes.
- $( β_i )$ son los coeficientes que representan la influencia de cada variable independiente en la variable dependiente.
- $( β_0 )$ es el término independiente o intercepto.
- $( ϵ )$ es el término de error o residuo, que representa la diferencia entre el valor real y el predicho.
El objetivo es estimar los coeficientes $( β )$ que minimicen el error entre los valores predichos y los observados. Para ello, se utiliza el método de mínimos cuadrados ordinarios (OLS), que busca minimizar la suma de los cuadrados de los residuos:
$$
\min_{β} \sum_{i=1}^{m} \left( y_i - β_0 - \sum_{j=1}^{n} β_j x_{ij} \right)^2
$$
Donde $( m )$ es el número de observaciones y $( n )$ es el número de variables independientes.
En Scikit-Learn, el modelo de regresión lineal se implementa mediante la clase LinearRegression
del módulo sklearn.linear_model
. Este modelo asume que existe una linealidad entre las variables y que los errores son independientes y siguen una distribución normal con media cero y varianza constante (homocedasticidad).
A continuación, se presentan algunos aspectos clave de la regresión lineal:
- Supuestos del modelo: Para que los resultados sean válidos, es importante verificar los supuestos de linealidad, independencia de los errores, homocedasticidad y normalidad de los residuos. La violación de estos supuestos puede conducir a estimaciones sesgadas o ineficientes.
- Coeficientes de regresión: Los coeficientes $( β_j )$ indican la magnitud y dirección de la influencia de cada variable independiente en la variable dependiente. Un coeficiente positivo implica una relación directa, mientras que uno negativo indica una relación inversa.
- Interpretación del intercepto: El término $( β_0 )$ representa el valor esperado de $( y )$ cuando todas las variables independientes son cero. Su interpretación debe hacerse con cautela, especialmente si el valor cero de las variables independientes no tiene sentido práctico.
- Bondad de ajuste: Para evaluar el desempeño del modelo, se utilizan métricas como el coeficiente de determinación ($( R^2 )$), que mide la proporción de la variabilidad de $( y )$ explicada por las variables independientes. Un $( R^2 )$ cercano a 1 indica un ajuste adecuado.
- Multicolinealidad: La presencia de alta correlación entre las variables independientes puede afectar la estimación de los coeficientes. Es importante detectar y manejar la multicolinealidad para mejorar la estabilidad del modelo.
Un ejemplo sencillo de cómo implementar una regresión lineal en Scikit-Learn es el siguiente:
from sklearn.linear_model import LinearRegression
import numpy as np
# Datos de ejemplo
X = np.array([[1], [2], [3], [4], [5]])
y = np.array([2, 4, 5, 4, 5])
# Crear y entrenar el modelo
modelo = LinearRegression()
modelo.fit(X, y)
# Coeficientes del modelo
print("Coeficiente:", modelo.coef_)
print("Intercepto:", modelo.intercept_)
En este ejemplo, se crea un modelo de regresión lineal simple para predecir $( y )$ a partir de una sola variable independiente $( X )$. Después de entrenar el modelo con el método fit
, es posible obtener los coeficientes y el intercepto del modelo.
Es importante destacar que la regresión lineal es sensible a los outliers y a los valores atípicos en los datos. Por lo tanto, es recomendable realizar un análisis exploratorio y considerar técnicas de preprocesamiento antes de ajustar el modelo.
Además, para problemas donde la relación entre las variables no es estrictamente lineal, es posible extender el modelo mediante transformaciones polinómicas o utilizando técnicas de regularización para mejorar la generalización.
Preprocesados específicos para regresiones lineales
La regresión lineal asume una relación lineal entre las variables independientes y la variable dependiente. Para garantizar que este supuesto se cumple y mejorar la calidad del modelo, es esencial realizar preprocesados específicos que aborden las particularidades de este tipo de regresiones.
Un paso fundamental es comprobar la linealidad entre cada variable independiente y la variable dependiente. Esto se puede evaluar visualizando gráficos de dispersión o utilizando técnicas como el coeficiente de correlación de Pearson. Si se detecta una relación no lineal, se pueden aplicar transformaciones a las variables, como el logaritmo, la raíz cuadrada o las potencias, para linearizar la relación y ajustar mejor el modelo.
La multicolinealidad entre las variables independientes puede afectar negativamente al modelo, ya que dificulta la estimación precisa de los coeficientes. Para detectar la multicolinealidad, se emplea el Factor de Inflación de la Varianza (VIF). Un VIF mayor a 5 o 10 indica problemas de multicolinealidad. En Python, podemos calcular el VIF utilizando la biblioteca statsmodels
:
from statsmodels.stats.outliers_influence import variance_inflation_factor
import pandas as pd
# Supongamos que X es un DataFrame con las variables independientes
vif_data = pd.DataFrame()
vif_data["Variable"] = X.columns
vif_data["VIF"] = [variance_inflation_factor(X.values, i) for i in range(len(X.columns))]
print(vif_data)
Si se identifica multicolinealidad, se pueden eliminar variables redundantes, combinar variables correlacionadas o utilizar métodos de reducción de la dimensionalidad como el Análisis de Componentes Principales (PCA).
La homocedasticidad es otro supuesto clave en la regresión lineal, que implica que la varianza de los errores es constante a lo largo de todos los valores de las variables independientes. Para verificar este supuesto, se puede analizar el gráfico de residuos frente a los valores predichos. En caso de heterocedasticidad, donde la varianza de los errores no es constante, se pueden aplicar transformaciones a la variable dependiente o utilizar métodos como la regresión ponderada.
El escalado de las variables es importante cuando las variables independientes tienen diferentes unidades o escalas. Aunque la regresión lineal no requiere escalado para obtener estimaciones correctas de los coeficientes, hacerlo puede mejorar la interpretabilidad y el rendimiento numérico del modelo, especialmente en presencia de regularización. El método más común es la estandarización, que centra las variables en cero y las escala a una desviación estándar de uno:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
La detección y tratamiento de outliers es crucial, ya que los valores atípicos pueden influir significativamente en los coeficientes del modelo. Se pueden utilizar métodos gráficos, como el boxplot, o técnicas estadísticas para identificar outliers. Una vez detectados, existen varias opciones: eliminarlos, transformarlos o utilizar modelos robustos como el Ridge Regression o el Lasso Regression, que incluyen términos de regularización para mitigar el efecto de los outliers.
El supuesto de normalidad de los errores establece que los residuos del modelo deben seguir una distribución normal. Aunque la regresión lineal es robusta a desviaciones de este supuesto en muestras grandes, verificar la normalidad puede ser útil. Se pueden utilizar pruebas estadísticas como el test de Shapiro-Wilk o representaciones gráficas como el Q-Q plot. Si los residuos no son normales, se pueden aplicar transformaciones a la variable dependiente para aproximar la normalidad.
En situaciones donde existen valores faltantes, es importante tratarlos adecuadamente antes de ajustar el modelo. Para la regresión lineal, es común utilizar imputación con la media o la mediana de la variable. Con scikit-learn
, podemos utilizar el SimpleImputer
para realizar esta tarea:
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='mean') # O 'median' según corresponda
X_imputed = imputer.fit_transform(X)
Además, es recomendable codificar las variables categóricas, ya que la regresión lineal requiere variables numéricas. La codificación one-hot es una técnica estándar para este propósito:
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(drop='first') # drop='first' para evitar multicolinealidad
X_encoded = encoder.fit_transform(categorical_features)
En cuanto a las interacciones entre variables, incluir términos de interacción puede mejorar el modelo si existe una relación conjunta entre variables independientes que afecta a la variable dependiente. Podemos generar términos de interacción utilizando PolynomialFeatures
:
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=1, interaction_only=True, include_bias=False)
X_interactions = poly.fit_transform(X)
Finalmente, es importante dividir el conjunto de datos en entrenamiento y prueba para evaluar adecuadamente el rendimiento del modelo y prevenir el sobreajuste. Usando train_test_split
de scikit-learn
:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_final, y, test_size=0.2, random_state=42)
Aplicando estos preprocesados específicos, nos aseguramos de que el modelo de regresión lineal cumpla con los supuestos necesarios y proporciona predicciones más fiables y precisas.
Regresión lineal simple
La regresión lineal simple es un modelo estadístico que permite explorar y cuantificar la relación entre una variable independiente y una variable dependiente mediante una recta. Este modelo asume que existe una relación lineal entre ambas variables, de forma que los cambios en la variable independiente producen cambios proporcionales en la variable dependiente.
Matemáticamente, la regresión lineal simple se expresa mediante la ecuación:
$$
y = β_0 + β_1 x + ε
$$
Donde:
- $( y )$ es la variable dependiente.
- $( x )$ es la variable independiente.
- $( β_0 )$ es el término independiente o intercepto.
- $( β_1 )$ es el coeficiente que representa la pendiente de la recta.
- $( ε )$ es el término de error o residuo, que captura la variabilidad no explicada por el modelo.
En Scikit-Learn, la clase LinearRegression
del módulo sklearn.linear_model
se utiliza para implementar la regresión lineal simple. Esta clase ofrece métodos para ajustar el modelo a los datos y realizar predicciones.
A continuación se muestra un ejemplo práctico de cómo utilizar LinearRegression
para llevar a cabo una regresión lineal simple:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
# Datos de ejemplo
X = np.array([1, 2, 3, 4, 5]).reshape(-1, 1)
y = np.array([2, 3, 5, 6, 5])
# Crear y ajustar el modelo
modelo = LinearRegression()
modelo.fit(X, y)
# Realizar predicciones
y_pred = modelo.predict(X)
# Visualizar los resultados
plt.scatter(X, y, color='blue', label='Datos reales')
plt.plot(X, y_pred, color='red', label='Predicción')
plt.xlabel('Variable independiente X')
plt.ylabel('Variable dependiente y')
plt.title('Regresión Lineal Simple')
plt.legend()
plt.show()
En este ejemplo, se importan las bibliotecas necesarias y se crean dos arrays de NumPy: X, que contiene los valores de la variable independiente, e y, que contiene los valores de la variable dependiente. Es importante que X tenga forma de matriz columna, por lo que se utiliza reshape(-1, 1)
.
El objeto LinearRegression
se instancia y se ajusta a los datos utilizando el método fit(X, y)
. Posteriormente, se realizan predicciones con el método predict(X)
. Finalmente, se visualizan los datos reales y la recta de regresión utilizando matplotlib.
Los coeficientes del modelo se pueden obtener a través de los atributos coef_
e intercept_
:
print(f"Coeficiente (pendiente): {modelo.coef_[0]:.4f}")
print(f"Término independiente (intercepto): {modelo.intercept_:.4f}")
Estos valores proporcionan información sobre la pendiente de la recta y el intercepto, lo que permite interpretar cómo influye la variable independiente en la dependiente. Un coeficiente positivo indica una relación directa, mientras que uno negativo indica una relación inversa.
Es fundamental evaluar el desempeño del modelo para verificar su capacidad predictiva. Una métrica comúnmente utilizada es el coeficiente de determinación $( R^2 )$, que mide la proporción de la variabilidad de la variable dependiente explicada por el modelo:
from sklearn.metrics import r2_score
r2 = r2_score(y, y_pred)
print(f"Coeficiente de determinación R^2: {r2:.4f}")
Un valor de $( R^2 )$ cercano a 1 indica que el modelo explica la mayor parte de la variabilidad observada en los datos. Sin embargo, es recomendable analizar también los residuos para detectar posibles patrones que puedan indicar una mala especificación del modelo.
La regresión lineal simple tiene aplicaciones en diversas áreas, como economía, ingeniería y ciencias sociales. Por ejemplo, se puede utilizar para predecir el consumo energético en función de la temperatura ambiental, o para estimar el rendimiento académico a partir del número de horas de estudio.
Es importante tener en cuenta que la regresión lineal simple asume varios supuestos:
- Linealidad: la relación entre las variables es lineal.
- Independencia: las observaciones son independientes entre sí.
- Homoscedasticidad: la varianza de los errores es constante.
- Normalidad de los errores: los residuos siguen una distribución normal.
La violación de estos supuestos puede afectar la validez del modelo y sus inferencias. Por ello, es recomendable realizar un análisis exploratorio y verificar el cumplimiento de los supuestos antes de interpretar los resultados.
Además, aunque la regresión lineal simple es una herramienta sencilla, puede ser insuficiente cuando existen múltiples variables que influyen en la variable dependiente. En estos casos, es conveniente utilizar modelos de regresión lineal múltiple o considerar relaciones no lineales.
En resumen, la regresión lineal simple es un método eficaz para modelar y entender la relación entre dos variables cuantitativas. Su implementación en Scikit-Learn es directa y permite integrar fácilmente este modelo en procesos de análisis y predicción en entornos avanzados de programación.
Regresión lineal múltiple
La regresión lineal múltiple es una extensión de la regresión lineal simple que permite modelar la relación entre una variable dependiente y múltiples variables independientes. Este modelo es fundamental cuando se desea analizar el impacto conjunto de varias variables predictoras sobre una respuesta continua.
Matemáticamente, el modelo se expresa como:
$$
y = β_0 + β_1 x_1 + β_2 x_2 + \dots + β_p x_p + ε
$$
Donde:
- $( y )$ es la variable dependiente.
- $( x_1, x_2, \dots, x_p )$ son las variables independientes.
- $( β_0 )$ es el término independiente o intercepto.
- $( β_1, β_2, \dots, β_p )$ son los coeficientes que cuantifican el efecto de cada variable independiente sobre $( y )$.
- $( ε )$ es el término de error, que representa la variabilidad no explicada por el modelo.
En Scikit-Learn, la regresión lineal múltiple se implementa de manera similar a la regresión lineal simple utilizando la clase LinearRegression
del módulo sklearn.linear_model
. La principal diferencia radica en que, en lugar de utilizar una única variable independiente, se emplea un conjunto de variables predictoras.
A continuación, se presenta un ejemplo práctico de cómo ajustar un modelo de regresión lineal múltiple con Scikit-Learn:
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
# Datos de ejemplo
data = {
'Superficie': [50, 60, 70, 80, 90],
'Habitaciones': [1, 2, 2, 3, 3],
'Antigüedad': [10, 15, 7, 8, 5],
'Precio': [200000, 250000, 300000, 350000, 400000]
}
df = pd.DataFrame(data)
# Variables independientes y dependiente
X = df[['Superficie', 'Habitaciones', 'Antigüedad']]
y = df['Precio']
# Crear y entrenar el modelo
modelo = LinearRegression()
modelo.fit(X, y)
# Coeficientes del modelo
print("Coeficientes:", modelo.coef_)
print("Intercepto:", modelo.intercept_)
En este ejemplo, se utiliza un conjunto de datos ficticio que representa las características de diferentes viviendas: superficie, habitaciones y antigüedad, y su precio correspondiente. Las variables independientes se almacenan en X, mientras que la variable dependiente es y.
Después de crear una instancia de LinearRegression
, se ajusta el modelo con el método fit
. Los coeficientes obtenidos reflejan el impacto individual de cada variable independiente sobre el precio de la vivienda. El intercepto representa el valor predicho de $( y )$ cuando todas las variables independientes son cero.
Para realizar predicciones con nuevos datos, se utiliza el método predict
:
# Nuevos datos para predicción
nuevas_viviendas = pd.DataFrame({
'Superficie': [85, 60],
'Habitaciones': [3, 2],
'Antigüedad': [2, 20]
})
# Predicción de precios
predicciones = modelo.predict(nuevas_viviendas)
print("Predicciones de precios:", predicciones)
Es esencial asegurarse de que los nuevos datos tengan las mismas características y estén preprocesados de la misma manera que los datos utilizados para entrenar el modelo.
Una ventaja de la regresión lineal múltiple es la capacidad de cuantificar el efecto parcial de cada variable independiente sobre la variable dependiente, manteniendo constantes las demás variables. Esto permite una comprensión más profunda de las relaciones entre las variables en estudio.
Sin embargo, es importante tener en cuenta aspectos como la multicolinealidad, que ocurre cuando las variables independientes están altamente correlacionadas entre sí. La multicolinealidad puede afectar la estabilidad y la interpretabilidad de los coeficientes estimados. Para detectar la multicolinealidad, se pueden calcular los Factores de Inflación de la Varianza (VIF) o analizar la matriz de correlación.
Otro aspecto crucial es evaluar el rendimiento del modelo. Además del coeficiente de determinación $( R^2 )$, es recomendable utilizar métricas como el Error Cuadrático Medio (MSE) o el Error Absoluto Medio (MAE):
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
# Predicciones sobre el conjunto de entrenamiento
y_pred = modelo.predict(X)
# Evaluación del modelo
mse = mean_squared_error(y, y_pred)
mae = mean_absolute_error(y, y_pred)
r2 = r2_score(y, y_pred)
print(f"MSE: {mse:.2f}")
print(f"MAE: {mae:.2f}")
print(f"Coeficiente de determinación R^2: {r2:.2f}")
Estas métricas proporcionan información sobre la precisión del modelo y permiten comparar su desempeño con otros modelos o configuraciones.
En escenarios con un gran número de variables independientes, es posible que algunas no contribuyan significativamente al modelo. En tales casos, es útil aplicar técnicas de selección de características para identificar y mantener sólo las variables más relevantes. El módulo sklearn.feature_selection
ofrece herramientas como SelectKBest
o RFE
(Eliminación Recursiva de Características) para este propósito.
Además, es frecuente que las variables independientes requieran algún tipo de preprocesamiento. Por ejemplo, si existen variables categóricas, es necesario transformarlas en variables numéricas mediante técnicas como la codificación one-hot. Esto se puede lograr con el OneHotEncoder
de Scikit-Learn:
from sklearn.preprocessing import OneHotEncoder
# Supongamos que 'Ubicación' es una variable categórica
df['Ubicación'] = ['Centro', 'Norte', 'Sur', 'Este', 'Oeste']
# Codificación one-hot
encoder = OneHotEncoder(drop='first', sparse_output=False)
ubicacion_encoded = encoder.fit_transform(df[['Ubicación']])
# Añadir las variables codificadas al conjunto de datos
X = np.hstack([X.values, ubicacion_encoded])
Es fundamental mantener consistencia entre el preprocesamiento realizado durante el entrenamiento y el aplicado a los nuevos datos para predicción.
Otra herramienta útil es el uso de pipelines para encadenar los pasos de preprocesamiento y modelado, garantizando un flujo de trabajo coherente y reproducible. Con Pipeline
de Scikit-Learn, se pueden automatizar estas tareas:
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
# Crear un pipeline con escalado y modelo
pipeline = Pipeline([
('escalado', StandardScaler()),
('modelo_regresion', LinearRegression())
], memory = None )
# Ajustar el pipeline
pipeline.fit(X, y)
# Realizar predicciones
predicciones = pipeline.predict(X)
El uso de pipelines facilita la gestión de transformaciones y asegura que todas las etapas se apliquen correctamente tanto en entrenamiento como en predicción.
La regresión lineal múltiple es una herramienta versátil para modelar relaciones lineales entre una variable dependiente y varias variables independientes. Su implementación en Scikit-Learn es sencilla y flexible, permitiendo incorporar diferentes técnicas de preprocesamiento y evaluación para mejorar el rendimiento y la interpretabilidad del modelo.
Regresión polinómica
La regresión polinómica es una técnica que amplía el modelo de regresión lineal para capturar relaciones no lineales entre las variables independientes y la variable dependiente. Aunque el modelo lineal se limita a relaciones lineales, es posible transformar las variables independientes mediante funciones polinómicas para ajustarse a patrones más complejos sin abandonar el marco lineal.
En Scikit-Learn, la regresión polinómica se implementa generando características polinómicas a partir de las variables originales y luego aplicando un modelo de regresión lineal sobre estas nuevas características. Esto se logra utilizando la clase PolynomialFeatures
del módulo sklearn.preprocessing
, que permite crear términos polinómicos de grado especificado.
A continuación se presenta un ejemplo práctico que ilustra cómo realizar una regresión polinómica utilizando Scikit-Learn:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
# Generación de datos sintéticos con numpy.random.Generator
generator = np.random.default_rng(42)
X = np.sort(5 * generator.random((40, 1)), axis=0)
y = np.sin(X).ravel() + generator.normal(0, 0.2, X.shape[0])
# Transformación de las características a polinómicas de grado 3
grado = 3
polinomio = PolynomialFeatures(degree=grado, include_bias=False)
X_polinomio = polinomio.fit_transform(X)
# Creación y entrenamiento del modelo de regresión lineal
modelo = LinearRegression()
modelo.fit(X_polinomio, y)
# Predicciones para visualización
X_fit = np.linspace(0, 5, 100).reshape(-1, 1)
X_fit_polinomio = polinomio.transform(X_fit)
y_pred = modelo.predict(X_fit_polinomio)
# Visualización de los resultados
plt.scatter(X, y, color='blue', label='Datos reales')
plt.plot(X_fit, y_pred, color='red', label='Regresión polinómica')
plt.xlabel('Variable independiente X')
plt.ylabel('Variable dependiente y')
plt.title('Regresión Polinómica de Grado 3')
plt.legend()
plt.show()
En este ejemplo:
- Se generan datos sintéticos que siguen una función no lineal para simular un escenario donde la regresión lineal no es suficiente.
- Se utiliza
PolynomialFeatures
para transformar X en un conjunto de características polinómicas de grado 3. - El modelo
LinearRegression
se ajusta sobre las características polinómicas, permitiendo modelar la relación no lineal original. - Se visualiza el ajuste del modelo sobre los datos, observando cómo la curva polinómica captura mejor la tendencia que una recta.
Es importante destacar que, aunque se utilizan transformaciones polinómicas, el modelo subyacente sigue siendo lineal en los parámetros, lo que mantiene las propiedades y ventajas de los modelos lineales. Esto significa que los coeficientes se estiman resolviendo un sistema de ecuaciones lineales, lo que es computacionalmente eficiente.
La creación de características polinómicas añade complejidad al modelo, por lo que es esencial considerar aspectos como el sobreajuste. Un grado polinómico demasiado alto puede ajustarse perfectamente a los datos de entrenamiento pero tener un rendimiento pobre en datos nuevos. Para mitigar este riesgo, se pueden utilizar técnicas de validación cruzada y evaluar métricas como el error cuadrático medio (MSE) en conjuntos de validación.
Por ejemplo, para evaluar el impacto del grado polinómico en el ajuste del modelo, se puede realizar un bucle que pruebe diferentes grados y calcule el MSE correspondiente:
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
# División de los datos en entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
grados = [1, 2, 3, 4, 5]
mse_train = []
mse_test = []
for grado in grados:
polinomio = PolynomialFeatures(degree=grado, include_bias=False)
X_train_polinomio = polinomio.fit_transform(X_train)
X_test_polinomio = polinomio.transform(X_test)
modelo = LinearRegression()
modelo.fit(X_train_polinomio, y_train)
y_train_pred = modelo.predict(X_train_polinomio)
y_test_pred = modelo.predict(X_test_polinomio)
mse_train.append(mean_squared_error(y_train, y_train_pred))
mse_test.append(mean_squared_error(y_test, y_test_pred))
# Visualización del error cuadrático medio
plt.plot(grados, mse_train, marker='o', label='MSE Entrenamiento')
plt.plot(grados, mse_test, marker='o', label='MSE Prueba')
plt.xlabel('Grado del polinomio')
plt.ylabel('Error cuadrático medio')
plt.title('Evaluación del sobreajuste según el grado polinómico')
plt.legend()
plt.show()
Este código permite observar cómo varía el error en los conjuntos de entrenamiento y prueba al aumentar el grado del polinomio. Un aumento significativo del error en el conjunto de prueba en comparación con el de entrenamiento indica sobreajuste.
La clase PolynomialFeatures
ofrece varios parámetros útiles:
- degree: especifica el grado máximo de los polinomios generados.
- include_bias: si es
True
, se incluye un término de sesgo (columna de unos). Por defecto esTrue
, pero al utilizarLinearRegression
, que ya incluye el intercepto, es conveniente establecerlo enFalse
para evitar la multicolinealidad. - interaction_only: si es
True
, sólo se generan términos de interacción entre características, sin potencias de una sola variable.
Además de la regresión polinómica, esta técnica permite capturar interacciones entre variables en modelos de regresión lineal múltiple. Por ejemplo, si se tiene más de una variable independiente, PolynomialFeatures
generará términos que representan interacciones entre ellas. Esto enriquece el modelo y puede mejorar su capacidad predictiva si dichas interacciones son relevantes.
Es fundamental tener en cuenta que el aumento del número de características puede conducir a problemas de alta dimensionalidad, especialmente con grados polinómicos elevados y múltiples variables independientes. Esto puede incrementar el tiempo de entrenamiento y requerir más memoria. Por ello, es recomendable aplicar métodos de regularización o selección de características cuando se trabaja con modelos polinómicos complejos.
Una alternativa para manejar este incremento en complejidad es utilizar modelos de regresión regularizados como Ridge o Lasso, que penalizan la magnitud de los coeficientes y ayudan a prevenir el sobreajuste. Por ejemplo:
from sklearn.linear_model import Ridge
# Modelo de regresión polinómica con regularización Ridge
modelo_ridge = Ridge(alpha=1.0)
modelo_ridge.fit(X_polinomio, y)
En este caso, el parámetro alpha controla la intensidad de la regularización. Un valor mayor implica una penalización más fuerte, lo que conduce a coeficientes más pequeños y, potencialmente, a un modelo más generalizable.
Otra consideración es el escalado de las características. Al generar características polinómicas, es posible que los valores resultantes tengan magnitudes muy diferentes, lo que puede afectar al entrenamiento del modelo. Por ello, es recomendable aplicar técnicas de escalado como la estandarización antes de generar las características polinómicas:
from sklearn.preprocessing import StandardScaler
# Escalado de las características
escalador = StandardScaler()
X_escalado = escalador.fit_transform(X)
# Generación de características polinómicas
polinomio = PolynomialFeatures(degree=grado, include_bias=False)
X_polinomio = polinomio.fit_transform(X_escalado)
El escalado asegura que todas las características contribuyan de manera equilibrada al ajuste del modelo.
En resumen, la regresión polinómica es una herramienta poderosa para capturar relaciones no lineales dentro del marco de los modelos lineales. Su implementación en Scikit-Learn es sencilla y flexible, permitiendo ajustar modelos complejos mediante la transformación de las variables originales y el uso de regresores lineales estándar.
Al trabajar con regresión polinómica, es crucial prestar atención a aspectos como el grado del polinomio, la posible aparición de sobreajuste y la necesidad de escalado y regularización. De esta manera, se pueden obtener modelos que no solo se ajusten bien a los datos de entrenamiento, sino que también tengan un buen rendimiento predictivo en datos nuevos.
Regresión regularizada
En la regresión lineal, es común enfrentar problemas de sobreajuste, especialmente cuando se trabaja con conjuntos de datos con alto número de variables o colinealidad entre ellas. La regularización es una técnica que permite mejorar la generalización del modelo, añadiendo una penalización a los coeficientes para evitar que tomen valores excesivamente grandes.
Existen principalmente tres tipos de regresiones regularizadas en Scikit-Learn:
- Regresión Ridge (Regresión con penalización L2)
- Regresión Lasso (Regresión con penalización L1)
- Regresión Elastic Net (Combinación de penalizaciones L1 y L2)
La aplicación de estas técnicas ayuda a controlar la complejidad del modelo y prevenir problemas derivados de la multicolinealidad.
Regresión Ridge
La Regresión Ridge añade una penalización al cuadrado de la magnitud de los coeficientes (norma L2) al minimizar la función de coste. Matemáticamente, el modelo se define como:
$$
\min_{β} \sum_{i=1}^{n} (y_i - X_i β)^2 + α \sum_{j=1}^{p} β_j^2
$$
Donde:
- $( α )$ es el parámetro de regularización que controla la fuerza de la penalización.
- $( β_j )$ son los coeficientes del modelo.
En Scikit-Learn, se implementa mediante la clase Ridge
del módulo sklearn.linear_model
. A continuación se muestra un ejemplo de cómo utilizarla:
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
# Supongamos que X y y son nuestros datos de características y etiquetas
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# Crear y entrenar el modelo Ridge
modelo_ridge = Ridge(alpha=1.0)
modelo_ridge.fit(X_train, y_train)
# Realizar predicciones
y_pred = modelo_ridge.predict(X_test)
El parámetro alpha controla la cantidad de regularización aplicada. Un valor más alto implica una mayor penalización a los coeficientes, lo que puede reducir el sobreajuste pero también puede subestimar la relación entre las variables.
Regresión Lasso
La Regresión Lasso incluye una penalización basada en la norma L1 de los coeficientes, favoreciendo soluciones donde algunos coeficientes son exactamente cero; es decir, realiza una selección de características automática. La función a minimizar es:
$$
\min_{β} \sum_{i=1}^{n} (y_i - X_i β)^2 + α \sum_{j=1}^{p} |β_j|
$$
Para implementarla en Scikit-Learn, se utiliza la clase Lasso
:
from sklearn.linear_model import Lasso
# Crear y entrenar el modelo Lasso
modelo_lasso = Lasso(alpha=0.1)
modelo_lasso.fit(X_train, y_train)
# Realizar predicciones
y_pred = modelo_lasso.predict(X_test)
La Regresión Lasso es útil cuando se sospecha que muchas de las variables independientes no contribuyen significativamente al modelo. Al forzar algunos coeficientes a cero, simplifica el modelo y mejora su interpretabilidad.
Regresión Elastic Net
La Regresión Elastic Net combina las penalizaciones L1 y L2, buscando un equilibrio entre la regularización de Ridge y la selección de características de Lasso. La función de coste es:
$$
\min_{β} \sum_{i=1}^{n} (y_i - X_i β)^2 + α \left( λ \sum_{j=1}^{p} |β_j| + (1 - λ) \sum_{j=1}^{p} β_j^2 \right)
$$
Donde $( λ )$ es el parámetro que controla la proporción entre las penalizaciones L1 y L2.
En Scikit-Learn, se implementa con la clase ElasticNet
:
from sklearn.linear_model import ElasticNet
# Crear y entrenar el modelo Elastic Net
modelo_enet = ElasticNet(alpha=0.1, l1_ratio=0.5)
modelo_enet.fit(X_train, y_train)
# Realizar predicciones
y_pred = modelo_enet.predict(X_test)
El parámetro l1_ratio corresponde a ( λ ) y toma valores entre 0 y 1. Un valor de 0 equivale a Ridge, mientras que un valor de 1 equivale a Lasso.
Selección del parámetro de regularización
La elección adecuada del parámetro alpha es crucial para el rendimiento del modelo. Una forma común de determinar el mejor valor es mediante validación cruzada. Scikit-Learn proporciona clases como RidgeCV
, LassoCV
y ElasticNetCV
que realizan esta tarea automáticamente.
Ejemplo con RidgeCV
:
from sklearn.linear_model import RidgeCV
# Lista de posibles valores de alpha
alphas = [0.1, 1.0, 10.0]
# Crear y entrenar el modelo Ridge con validación cruzada
modelo_ridge_cv = RidgeCV(alphas=alphas, cv=5)
modelo_ridge_cv.fit(X_train, y_train)
# Mejor valor de alpha
print("Mejor alpha:", modelo_ridge_cv.alpha_)
En este caso, el modelo evalúa diferentes valores de alpha utilizando validación cruzada con 5 particiones y selecciona el que proporciona el mejor desempeño.
Interpretación de los coeficientes
En modelos regularizados, los coeficientes pueden ser más pequeños en magnitud debido a la penalización aplicada. En el caso de Lasso, algunos coeficientes pueden ser exactamente cero, lo que facilita la identificación de variables relevantes.
Es importante tener en cuenta que la regularización introduce un sesgo en el modelo, pero a cambio puede reducir la varianza y mejorar la capacidad de generalización.
Comparación de los modelos
La elección entre Ridge, Lasso y Elastic Net depende de las características del conjunto de datos:
- Ridge es adecuado cuando todas las variables tienen algún grado de influencia y se busca reducir el impacto de la multicolinealidad.
- Lasso es útil cuando se desea realizar selección de características, ya que puede eliminar variables irrelevantes.
- Elastic Net es conveniente cuando hay muchas variables correlacionadas y se necesita un equilibrio entre las propiedades de Ridge y Lasso.
Ejemplo práctico
A continuación se muestra un ejemplo completo que compara estos tres tipos de regresión:
import numpy as np
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# Generar datos sintéticos
X, y = make_regression(n_samples=100, n_features=20, noise=0.1, random_state=42)
# Dividir los datos en entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# Crear instancias de los modelos
modelos = {
'Regresión Lineal': LinearRegression(),
'Regresión Ridge': Ridge(alpha=1.0),
'Regresión Lasso': Lasso(alpha=0.1),
'Regresión Elastic Net': ElasticNet(alpha=0.1, l1_ratio=0.5)
}
# Entrenar y evaluar los modelos
for nombre, modelo in modelos.items():
modelo.fit(X_train, y_train)
y_pred = modelo.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print(f"{nombre} - Error cuadrático medio: {mse:.4f}")
Este ejemplo permite comparar el rendimiento de cada modelo en términos del error cuadrático medio (MSE) en el conjunto de prueba.
Uso de Pipeline para regularización
Para garantizar un flujo de trabajo coherente y reproducible, se recomienda utilizar pipelines que incluyan etapas de preprocesamiento y modelado. Por ejemplo:
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
pipeline = Pipeline([
('escalado', StandardScaler()),
('ridge', Ridge(alpha=1.0))
], memory = None )
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
El escalado de las variables es especialmente importante en modelos regularizados, ya que la regularización afecta de manera diferente a variables con distintas escalas.
Interpretabilidad de las regresiones en scikit learn
La interpretabilidad es un aspecto crucial en los modelos de regresión, ya que permite comprender cómo las variables independientes afectan a la variable dependiente. En scikit-learn, existen herramientas y métodos que facilitan el análisis e interpretación de los modelos de regresión, proporcionando una visión más profunda de las relaciones entre las variables.
Coeficientes y términos independientes
En los modelos de regresión lineal, como LinearRegression
, los coeficientes almacenados en el atributo coef_
representan la influencia de cada variable independiente en la variable dependiente. Un coeficiente positivo indica una relación directa, mientras que uno negativo indica una relación inversa. El término independiente, almacenado en intercept_
, representa el valor predicho cuando todas las variables independientes son cero.
Por ejemplo:
from sklearn.linear_model import LinearRegression
import numpy as np
# Datos de ejemplo
X = np.array([[1, 2], [2, 0], [3, 1], [4, 3]])
y = np.array([6, 8, 9, 11])
# Ajustar el modelo
modelo = LinearRegression()
modelo.fit(X, y)
# Coeficientes e intercepto
print("Coeficientes:", modelo.coef_)
print("Intercepto:", modelo.intercept_)
Este código ajusta un modelo de regresión lineal y muestra los coeficientes asociados a cada variable independiente, permitiendo interpretar su impacto en la variable dependiente.
Importancia de las variables
Para evaluar la relevancia de cada variable en el modelo, es común analizar la magnitud de los coeficientes. Sin embargo, cuando las variables están en diferentes escalas, es recomendable estandarizarlas antes del ajuste para que los coeficientes sean comparables.
from sklearn.preprocessing import StandardScaler
# Escalado de las variables independientes
escalador = StandardScaler()
X_escalado = escalador.fit_transform(X)
# Ajuste del modelo con variables escaladas
modelo.fit(X_escalado, y)
print("Coeficientes escalados:", modelo.coef_)
Al estandarizar las variables, los coeficientes reflejan la importancia relativa de cada variable, facilitando su interpretación y comparación.
Intervalos de confianza
Aunque scikit-learn no proporciona directamente los intervalos de confianza de los coeficientes, es posible calcularlos utilizando bibliotecas complementarias como statsmodels
. Estos intervalos ofrecen información sobre la precisión de las estimaciones y permiten determinar si un coeficiente es significativamente diferente de cero.
import statsmodels.api as sm
# Añadir constante para el intercepto
X_con_constante = sm.add_constant(X)
# Ajuste del modelo con statsmodels
modelo_sm = sm.OLS(y, X_con_constante).fit()
print(modelo_sm.summary())
El resumen generado incluye los coeficientes, sus errores estándar, valores t y p-valores, proporcionando una comprensión más profunda del modelo y la significancia estadística de las variables.
Diagnóstico del modelo
Para evaluar el rendimiento y la adecuación del modelo, es útil analizar los residuos y verificar los supuestos de la regresión lineal. Un método común es visualizar los residuos frente a los valores predichos o las variables independientes.
import matplotlib.pyplot as plt
# Residuos
residuos = y - modelo.predict(X)
# Gráfico de residuos
plt.scatter(modelo.predict(X), residuos)
plt.hlines(y=0, xmin=min(modelo.predict(X)), xmax=max(modelo.predict(X)), colors='red')
plt.xlabel('Valores predichos')
plt.ylabel('Residuos')
plt.title('Gráfico de residuos')
plt.show()
Un patrón aleatorio en el gráfico de residuos sugiere que los supuestos de homocedasticidad y linealidad se cumplen, mientras que patrones sistemáticos indican potenciales problemas en el modelo.
Puntuaciones de influencia
La detección de valores atípicos y observaciones influyentes es esencial para garantizar la robustez del modelo. El criterio de Distancia de Cook mide el efecto de eliminar cada observación en los coeficientes del modelo.
import statsmodels.stats.outliers_influence as sm_influence
influencia = sm_influence.OLSInfluence(modelo_sm)
influence = influencia.cooks_distance[0]
# Gráfico de la distancia de Cook
plt.stem(np.arange(len(influence)), influence, markerfmt=",")
plt.xlabel('Observación')
plt.ylabel('Distancia de Cook')
plt.title('Detección de observaciones influyentes')
plt.show()
Observaciones con una distancia de Cook elevada pueden estar afectando desproporcionadamente al modelo y deberían ser analizadas con detalle.
Importancia de características con modelos regularizados
En modelos de regresión regularizada como Lasso o Ridge, los coeficientes también indican la importancia de las variables. En particular, Lasso puede establecer coeficientes exactamente a cero, realizando una selección de características implícita.
from sklearn.linear_model import Lasso
# Modelo Lasso
modelo_lasso = Lasso(alpha=0.1)
modelo_lasso.fit(X, y)
print("Coeficientes Lasso:", modelo_lasso.coef_)
Las variables con coeficientes diferentes de cero se consideran relevantes, lo que simplifica la interpretación en conjuntos de datos con muchas características.
Gráficos de dependencia parcial
Los gráficos de dependencia parcial (PDP) ilustran la relación entre una o dos variables independientes y la variable dependiente, manteniendo constantes las demás variables. En scikit-learn, se pueden generar estos gráficos utilizando PartialDependenceDisplay
.
from sklearn.inspection import PartialDependenceDisplay
# Generar gráfico de dependencia parcial para la primera variable
PartialDependenceDisplay.from_estimator(modelo, X, [0])
plt.show()
Estos gráficos ayudan a visualizar el efecto marginal de las variables en el modelo, facilitando su interpretación.
Importancia permutada de características
La importancia permutada evalúa la disminución en la puntuación del modelo cuando se permutan aleatoriamente los valores de una característica. Una disminución significativa indica que la variable es importante para el modelo.
from sklearn.inspection import permutation_importance
# Importancia permutada
resultado = permutation_importance(modelo, X, y, n_repeats=10, random_state=42)
importancias = resultado.importances_mean
indices = np.argsort(importancias)[::-1]
for idx in indices:
print(f"Variable {idx}, Importancia: {importancias[idx]:.4f}")
Este método es especialmente útil en modelos complejos donde la interpretación directa de los coeficientes no es trivial.
Coeficiente de determinación ajustado
El coeficiente de determinación ajustado (( R^2 ) ajustado) considera el número de variables en el modelo y es una medida más conservadora del ajuste del modelo. Aunque scikit-learn no lo calcula automáticamente, es sencillo computarlo manualmente.
from sklearn.metrics import r2_score
# Coeficiente de determinación
r2 = r2_score(y, modelo.predict(X))
# Número de observaciones y variables
n = X.shape[0]
p = X.shape[1]
# Cálculo del R^2 ajustado
r2_ajustado = 1 - (1 - r2) * (n - 1) / (n - p - 1)
print(f"R^2 ajustado: {r2_ajustado:.4f}")
Un $( R^2 )$ ajustado más alto sugiere que el modelo explica mejor la variabilidad de los datos, teniendo en cuenta el número de variables utilizadas.
Interpretación de modelos no lineales
En modelos de regresión no lineales, como la regresión polinómica, la interpretación de los coeficientes puede ser menos intuitiva. En estos casos, los gráficos de dependencia parcial y la importancia permutada son herramientas valiosas para entender las relaciones en el modelo.
Además, para modelos basados en árboles de decisión o algoritmos de conjunto, métodos como la importancia de las características basada en la reducción de la impureza pueden proporcionar información sobre la relevancia de las variables.
Utilización de SHAP y LIME
Para interpretaciones más avanzadas, se pueden emplear herramientas externas como SHAP (SHapley Additive exPlanations) y LIME (Local Interpretable Model-agnostic Explanations). Estas bibliotecas ofrecen explicaciones locales y globales del modelo, aunque requieren instalación y configuración adicionales.
import shap
# Crear un explainer
explainer = shap.Explainer(modelo, X)
shap_values = explainer(X)
# Gráfico resumen de SHAP
shap.summary_plot(shap_values, X)
Estos métodos permiten desglosar las predicciones individuales y entender cómo cada variable contribuye a la predicción, mejorando la transparencia del modelo.
Ejercicios de esta lección Regresión lineal
Evalúa tus conocimientos de esta lección Regresión lineal con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Todas las lecciones de ScikitLearn
Accede a todas las lecciones de ScikitLearn y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Aprendizaje Automático
Introducción Y Entorno
Introducción E Instalación
Introducción Y Entorno
Introducción Al Preprocesamiento De Datos
Preprocesamiento De Datos
Identificación Y Tratamiento De Valores Faltantes
Preprocesamiento De Datos
Escalado De Datos
Preprocesamiento De Datos
Normalización De Datos
Preprocesamiento De Datos
Codificación De Variables Categóricas
Preprocesamiento De Datos
Ingeniería De Características
Preprocesamiento De Datos
Selección De Características
Preprocesamiento De Datos
Extracción De Características
Preprocesamiento De Datos
Particionamiento De Datos
Preprocesamiento De Datos
Preprocesamiento De Datos Desbalanceados
Preprocesamiento De Datos
Introducción A La Regresión
Regresión
Regresión Lineal
Regresión
Regresión Knn Kneighborsregressor
Regresión
Regresión Svm Con Svr
Regresión
Regresión Con Árboles Decisiontreeregressor
Regresión
Regresión Con Algoritmos De Conjunto
Regresión
Introducción A La Clasificación
Clasificación
Clasificación Con Regresión Logística
Clasificación
Clasificación Knn Kneighborsclassifier
Clasificación
Clasificación Svm Con Svc
Clasificación
Clasificación Con Árboles Decisiontreeclassifier
Clasificación
Clasificación Con Algoritmos De Conjunto
Clasificación
Reducción De La Dimensionalidad Con Pca
Aprendizaje No Supervisado
Clustering Con Kmeans
Aprendizaje No Supervisado
Clustering Jerárquico
Aprendizaje No Supervisado
Clustering De Densidad Con Dbscan
Aprendizaje No Supervisado
Preprocesamiento De Textos Para Nlp
Nlp
Representación De Texto Y Extracción De Características
Nlp
Clasificación De Texto Con Scikit Learn
Nlp
Análisis De Sentimiento
Nlp
Técnicas Avanzadas De Extracción De Características
Nlp
Introducción Al Análisis De Series Temporales
Series Temporales
Preprocesamiento De Datos De Series Temporales
Series Temporales
Ingeniería De Características Para Series Temporales
Series Temporales
Transformación Y Escalado De Series Temporales
Series Temporales
Validación Y Evaluación De Modelos En Series Temporales
Series Temporales
Validación Y Evaluación De Modelos
Validación De Modelos
Técnicas De Validación Cruzada
Validación De Modelos
Métricas De Regresión
Validación De Modelos
Métricas De Clasificación
Validación De Modelos
Ajuste De Hiperparámetros
Validación De Modelos
Introducción A Pipelines
Pipelines Y Despliegue
Creación De Pipelines Básicos
Pipelines Y Despliegue
Preprocesamiento De Datos Con Pipelines
Pipelines Y Despliegue
Pipelines Y Validación Cruzada
Pipelines Y Despliegue
Pipelines Con Columntransformer
Pipelines Y Despliegue
Exportar E Importar Pipelines
Pipelines Y Despliegue
Objetivos de aprendizaje de esta lección
- Comprender los fundamentos teóricos de la regresión lineal y sus supuestos.
- Implementar modelos de regresión lineal simple y múltiple utilizando Scikit-Learn.
- Aplicar regresión polinómica para capturar relaciones no lineales en los datos.
- Emplear técnicas de regularización como Ridge, Lasso y Elastic Net para mejorar la generalización del modelo.
- Realizar preprocesado específico para regresiones lineales, incluyendo escalado y detección de multicolinealidad.
- Interpretar y evaluar modelos de regresión lineal mediante métricas y gráficos de residuos.