ScikitLearn
Tutorial ScikitLearn: Clasificación con Regresión logística
Scikit Learn: Regresión logística. Aprende a aplicar regresión logística para clasificación, incluyendo teoría, implementación, preprocesamiento y análisis de resultados.
Aprende ScikitLearn GRATIS y certifícateIntroducción teórica a la regresión logística para clasificación
La regresión logística es un modelo estadístico utilizado para predecir la probabilidad de que ocurra un evento específico. A diferencia de la regresión lineal, que se emplea para variables de salida continuas, la regresión logística se aplica cuando la variable objetivo es categórica, comúnmente binaria.
En el corazón de la regresión logística se encuentra la función sigmoide, también conocida como función logística. Esta función toma cualquier valor real y lo transforma en un valor entre 0 y 1, facilitando la interpretación como una probabilidad. Matemáticamente, la función sigmoide se define como:
$$
\text{sigmoide}(z) = \frac{1}{1 + e^{-z}}
$$
Donde $( z )$ es una combinación lineal de las variables de entrada y sus coeficientes. Este modelo lineal es similar al utilizado en la regresión lineal, pero el resultado se transforma mediante la función sigmoide para restringirlo al rango [0, 1].
La función de enlace que relaciona la probabilidad de la clase positiva con las variables independientes es el logit. El logit es el logaritmo natural de las probabilidades (odds) de que ocurra el evento:
$$
\text{logit}(p) = \ln\left(\frac{p}{1 - p}\right)
$$
Aquí, $( p )$ representa la probabilidad de la clase positiva. Al aplicar la regresión logística, modelamos el logit de la probabilidad como una combinación lineal de las variables predictoras:
$$
\text{logit}(p) = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \dots + \beta_n x_n
$$
Los coeficientes $( \beta_i )$ representan la influencia de cada variable independiente $( x_i )$ en el logit de la probabilidad. Estos coeficientes se estiman mediante el método de máxima verosimilitud, buscando los parámetros que maximizan la probabilidad de observar los datos dados los parámetros del modelo.
La frontera de decisión es el punto en el que el modelo decide entre una clase u otra. En el caso binario, suele establecerse un umbral de 0.5, donde si la probabilidad predicha es mayor o igual a 0.5, se asigna a la clase positiva; de lo contrario, a la clase negativa. Sin embargo, este umbral puede ajustarse según las necesidades específicas del problema, especialmente cuando las clases están desbalanceadas.
Un aspecto clave es la interpretación de los coeficientes. En la regresión logística, el exponente de un coeficiente $(( e^{\beta_i} ))$ representa el cambio en las odds asociado con un incremento unitario en la variable $( x_i )$, manteniendo las otras variables constantes. Esto permite entender cómo influye cada variable en la probabilidad de que ocurra el evento.
A continuación, se presenta un ejemplo práctico utilizando scikit-learn para ilustrar la implementación de una regresión logística:
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
# Generación de datos sintéticos utilizando un generador aleatorio
rng = np.random.default_rng(seed=42) # Generador con semilla
X = rng.random((1000, 2)) # Generar datos aleatorios
y = (X[:, 0] + X[:, 1] > 1).astype(int) # Etiquetas basadas en la suma de las características
# División en conjuntos de entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Creación y entrenamiento del modelo
modelo = LogisticRegression(max_iter=1000, random_state=42) # Asegurar convergencia con max_iter
modelo.fit(X_train, y_train)
# Predicción y evaluación
accuracy = modelo.score(X_test, y_test)
print(f"Precisión del modelo: {accuracy:.2f}")
En este ejemplo, se generan datos aleatorios y se establece una regla para asignar etiquetas binarias. El modelo de regresión logística se entrena con estos datos y se calcula la precisión en el conjunto de prueba.
La regresión logística también se extiende a problemas de clasificación multiclase utilizando métodos como one-vs-rest (OvR) o softmax. En scikit-learn, el modelo LogisticRegression
maneja automáticamente la clasificación multiclase mediante el esquema OvR o multiclass multinomial, especificado en el parámetro multi_class
.
Es importante considerar el problema de la colinealidad entre variables independientes, ya que puede afectar la estabilidad y la interpretabilidad de los coeficientes. Técnicas como la regularización L1 y L2 pueden incorporarse para penalizar coeficientes grandes y reducir el sobreajuste.
Por ejemplo, para aplicar regularización L2:
modelo_reg = LogisticRegression(penalty='l2', C=1.0)
modelo_reg.fit(X_train, y_train)
El parámetro C
controla la fuerza de la regularización; valores más pequeños de C
implican una mayor penalización.
Finalmente, la regresión logística asume que las variables independientes y el logit de la probabilidad tienen una relación lineal. Aunque es flexible, si esta suposición no se cumple, puede ser necesario transformar las variables o considerar modelos más complejos.
Preprocesados específicos para regresión logística
La regresión logística es un modelo lineal que se utiliza para clasificación binaria y multiclase. Aunque es robusto y flexible, para obtener resultados óptimos es crucial realizar ciertos preprocesados específicos que mejoran su rendimiento y estabilidad.
Un aspecto fundamental es el escalado de las variables independientes. Aunque la regresión logística no es tan sensible a las escalas como otros algoritmos, el uso de regularización, que es común en LogisticRegression
de scikit-learn, hace que el escalado sea importante. La regularización penaliza los coeficientes grandes, y si las variables están en diferentes escalas, esto puede afectar la magnitud de los coeficientes y, por ende, el rendimiento del modelo.
Para estandarizar las características, se utiliza StandardScaler
de scikit-learn, que transforma las variables para que tengan media cero y desviación estándar uno:
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
# Supongamos que tenemos datos X e y
X = ... # Matriz de características
y = ... # Vector de etiquetas
# 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)
# Aplicación del escalado
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Entrenamiento del modelo
modelo = LogisticRegression()
modelo.fit(X_train_scaled, y_train)
# Evaluación del modelo
score = modelo.score(X_test_scaled, y_test)
print(f"Precisión del modelo: {score:.2f}")
Otro preprocesado importante es la codificación de variables categóricas. La regresión logística requiere que las variables de entrada sean numéricas. Para transformar las variables categóricas, se suele utilizar la codificación one-hot, que convierte cada categoría en una nueva variable binaria.
Con OneHotEncoder
de scikit-learn, podemos realizar esta transformación de manera eficiente:
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
# Supongamos que 'X' contiene variables numéricas y categóricas
categorical_features = ['columna_categórica1', 'columna_categórica2']
numeric_features = ['columna_numérica1', 'columna_numérica2']
# Definición del transformador para las variables categóricas
one_hot = OneHotEncoder(drop='first')
# Creación del transformador de columnas
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features),
('cat', one_hot, categorical_features)
])
# Aplicación del preprocesado
X_train_processed = preprocessor.fit_transform(X_train)
X_test_processed = preprocessor.transform(X_test)
# Entrenamiento del modelo con los datos preprocesados
modelo = LogisticRegression()
modelo.fit(X_train_processed, y_train)
Es importante notar que en la codificación one-hot, hemos utilizado el argumento drop='first'
para evitar la trampa de la multicolinealidad, que ocurre cuando las variables categóricas codificadas son linealmente dependientes. Al eliminar una categoría, prevenimos este problema.
La detección y tratamiento de valores atípicos es otro preprocesado relevante. Los valores atípicos pueden afectar negativamente a la regresión logística, especialmente si se utiliza regularización. Una forma de identificar valores atípicos es mediante el análisis de los cuartiles y el cálculo de los rangos intercuartílicos (IQR). Una vez identificados, podemos optar por eliminarlos o transformarlos.
Por ejemplo, para limitar los valores extremos, podemos aplicar una técnica de capping o truncamiento:
import numpy as np
import pandas as pd
# Supongamos que 'X_train' es un DataFrame de pandas
for columna in numeric_features:
percentil_25 = X_train[columna].quantile(0.25)
percentil_75 = X_train[columna].quantile(0.75)
iqr = percentil_75 - percentil_25
limite_inferior = percentil_25 - 1.5 * iqr
limite_superior = percentil_75 + 1.5 * iqr
X_train[columna] = X_train[columna].clip(limite_inferior, limite_superior)
Además, la selección de características puede mejorar el rendimiento y la interpretabilidad del modelo. La regresión logística asume independencia entre variables predictoras; por tanto, reducir la colinealidad entre ellas es beneficioso. Podemos utilizar técnicas como el Análisis de Componentes Principales (PCA) o eliminar variables altamente correlacionadas.
Por ejemplo, para eliminar variables con alta correlación:
correlacion = X_train.corr().abs()
matriz_superior = correlacion.where(np.triu(np.ones(correlacion.shape), k=1).astype(bool))
columnas_a_eliminar = [columna for columna in matriz_superior.columns if any(matriz_superior[columna] > 0.9)]
X_train_reducido = X_train.drop(columns=columnas_a_eliminar)
X_test_reducido = X_test.drop(columns=columnas_a_eliminar)
En situaciones donde las clases están desbalanceadas, es decir, una clase tiene significativamente más muestras que la otra, la regresión logística puede inclinarse a predecir siempre la clase mayoritaria. Para abordar este problema, podemos ajustar el parámetro class_weight
del modelo:
modelo = LogisticRegression(class_weight='balanced')
modelo.fit(X_train_processed, y_train)
El argumento class_weight='balanced'
asigna pesos inversamente proporcionales a las clases según sus frecuencias, equilibrando su influencia en el entrenamiento.
También es posible utilizar técnicas de sobremuestreo o submuestreo antes del entrenamiento. Por ejemplo, el sobremuestreo con SMOTE (Synthetic Minority Over-sampling Technique) genera muestras sintéticas de la clase minoritaria:
from imblearn.over_sampling import SMOTE
# Aplicación de SMOTE al conjunto de entrenamiento
smote = SMOTE(random_state=42)
X_train_balanced, y_train_balanced = smote.fit_resample(X_train_processed, y_train)
# Entrenamiento del modelo con los datos balanceados
modelo = LogisticRegression()
modelo.fit(X_train_balanced, y_train_balanced)
Es importante ser cauteloso con el sobremuestreo para evitar sobreajuste, especialmente cuando el conjunto de datos es pequeño.
Finalmente, añadir términos de interacción o transformar variables puede capturar relaciones no lineales entre variables y mejorar el ajuste del modelo. Podemos generar estas características adicionales utilizando PolynomialFeatures
de scikit-learn:
from sklearn.preprocessing import PolynomialFeatures
# Generación de términos polinómicos de grado 2
poly = PolynomialFeatures(degree=2, interaction_only=True, include_bias=False)
X_train_poly = poly.fit_transform(X_train_processed)
X_test_poly = poly.transform(X_test_processed)
# Entrenamiento del modelo con las nuevas características
modelo = LogisticRegression()
modelo.fit(X_train_poly, y_train)
Con interaction_only=True
, se crean únicamente los términos de interacción sin potencias cuadráticas, lo cual puede reducir la complejidad del modelo.
Modelado con LogisticRegression
La clase LogisticRegression
de scikit-learn es una implementación ampliamente utilizada para resolver problemas de clasificación mediante regresión logística. Este modelo permite ajustar relaciones entre variables independientes y una variable objetivo categórica, proporcionando probabilidades y asignaciones de clase.
Para comenzar, es necesario importar las bibliotecas fundamentales:
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
Supongamos que disponemos de un conjunto de datos relacionado con la predicción de enfermedades cardíacas. Cargamos los datos utilizando pandas:
# Carga de datos
datos = pd.read_csv('enfermedad_cardiaca.csv')
Antes de proceder al modelado, es habitual separar las características (X) de la variable objetivo (y):
# Separación de características y variable objetivo
X = datos.drop('tiene_enfermedad', axis=1)
y = datos['tiene_enfermedad']
Dividimos el conjunto de datos en entrenamiento y prueba usando train_test_split
, asegurando una evaluación imparcial del modelo:
# División en conjuntos de entrenamiento y prueba
X_entrenamiento, X_prueba, y_entrenamiento, y_prueba = train_test_split(
X, y, test_size=0.2, random_state=42)
Creamos una instancia del modelo LogisticRegression
sin especificar parámetros adicionales:
# Creación del modelo
modelo = LogisticRegression()
Entrenamos el modelo con el conjunto de entrenamiento utilizando el método fit
:
# Entrenamiento del modelo
modelo.fit(X_entrenamiento, y_entrenamiento)
Una vez entrenado, podemos realizar predicciones sobre el conjunto de prueba:
# Predicciones sobre el conjunto de prueba
y_pred = modelo.predict(X_prueba)
Para evaluar el rendimiento del modelo, calculamos la exactitud (accuracy):
# Evaluación del modelo
exactitud = accuracy_score(y_prueba, y_pred)
print(f'Exactitud del modelo: {exactitud:.2f}')
El atributo coef_
del modelo proporciona los coeficientes estimados para cada característica:
# Coeficientes del modelo
coeficientes = modelo.coef_
print('Coeficientes del modelo:', coeficientes)
Si deseamos obtener las probabilidades predichas para cada clase, utilizamos el método predict_proba
:
# Probabilidades predichas
probabilidades = modelo.predict_proba(X_prueba)
print('Probabilidades predichas:', probabilidades)
Es frecuente que las características necesiten escalado o normalización. Podemos incluir estos preprocesados dentro de un Pipeline para simplificar el flujo de trabajo:
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
# Creación del pipeline
pipeline = Pipeline([
('escalado', StandardScaler()),
('modelo', LogisticRegression())
], memory = None)
# Entrenamiento con el pipeline
pipeline.fit(X_entrenamiento, y_entrenamiento)
# Predicciones y evaluación
y_pred = pipeline.predict(X_prueba)
exactitud = accuracy_score(y_prueba, y_pred)
print(f'Exactitud del modelo con escalado: {exactitud:.2f}')
En problemas donde las clases están desbalanceadas, es útil ajustar el parámetro class_weight
para manejar este desequilibrio:
# Modelo con ajuste de pesos de clase
modelo_balanced = LogisticRegression(class_weight='balanced')
modelo_balanced.fit(X_entrenamiento, y_entrenamiento)
# Evaluación del modelo ajustado
y_pred_balanced = modelo_balanced.predict(X_prueba)
exactitud_balanced = accuracy_score(y_prueba, y_pred_balanced)
print(f'Exactitud del modelo balanceado: {exactitud_balanced:.2f}')
Para mejorar la generalización, es recomendable utilizar validación cruzada. Con cross_val_score
, podemos obtener una estimación más fiable del rendimiento:
from sklearn.model_selection import cross_val_score
# Validación cruzada
puntuaciones = cross_val_score(modelo, X, y, cv=5, scoring='accuracy')
print(f'Exactitud media en validación cruzada: {puntuaciones.mean():.2f}')
La regresión logística en scikit-learn también soporta la clasificación multiclase. Por defecto, utiliza el esquema one-vs-rest, pero podemos especificar multi_class='multinomial'
para utilizar el método softmax:
# Modelo para clasificación multiclase
modelo_multiclase = LogisticRegression(multi_class='multinomial', solver='lbfgs')
modelo_multiclase.fit(X_entrenamiento, y_entrenamiento)
# Evaluación del modelo multiclase
y_pred_multiclase = modelo_multiclase.predict(X_prueba)
exactitud_multiclase = accuracy_score(y_prueba, y_pred_multiclase)
print(f'Exactitud del modelo multiclase: {exactitud_multiclase:.2f}')
En situaciones donde hay colinealidad entre variables, la regularización ayuda a mejorar la estabilidad del modelo. Podemos aplicar regularización L1 o L2 ajustando el parámetro penalty
:
# Modelo con regularización L1
modelo_l1 = LogisticRegression(penalty='l1', solver='liblinear', C=1.0)
modelo_l1.fit(X_entrenamiento, y_entrenamiento)
# Modelo con regularización L2
modelo_l2 = LogisticRegression(penalty='l2', C=1.0)
modelo_l2.fit(X_entrenamiento, y_entrenamiento)
El parámetro C
controla la fuerza de la regularización; valores más pequeños implican una penalización mayor.
Para analizar métricas más allá de la exactitud, como la matriz de confusión, utilizamos herramientas adicionales:
from sklearn.metrics import confusion_matrix, classification_report
# Matriz de confusión
matriz_confusion = confusion_matrix(y_prueba, y_pred)
print('Matriz de confusión:\n', matriz_confusion)
# Informe de clasificación
informe = classification_report(y_prueba, y_pred)
print('Informe de clasificación:\n', informe)
En ocasiones, es útil visualizar la curva ROC y calcular el AUC para evaluar la discriminación del modelo:
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
# Cálculo de las probabilidades para la clase positiva
probabilidades_pos = modelo.predict_proba(X_prueba)[:, 1]
# Cálculo de la curva ROC
fpr, tpr, thresholds = roc_curve(y_prueba, probabilidades_pos)
roc_auc = auc(fpr, tpr)
# Gráfico de la curva ROC
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'Curva ROC (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('Tasa de Falsos Positivos')
plt.ylabel('Tasa de Verdaderos Positivos')
plt.title('Curva ROC')
plt.legend(loc='lower right')
plt.show()
Para finalizar, es posible guardar el modelo entrenado para su uso posterior empleando joblib
:
import joblib
# Guardar el modelo
joblib.dump(modelo, 'modelo_logistic_regression.pkl')
# Cargar el modelo
modelo_cargado = joblib.load('modelo_logistic_regression.pkl')
De esta manera, el modelo puede ser desplegado o utilizado en aplicaciones en producción sin necesidad de reentrenamiento.
Parámetros de LogisticRegression
La clase LogisticRegression
de scikit-learn ofrece un conjunto de parámetros que permiten personalizar y optimizar el comportamiento del modelo según las necesidades específicas de cada problema de clasificación. A continuación, se describen los principales parámetros y cómo influyen en el modelo.
penalty
: Especifica la norma utilizada en la penalización de la regularización. Los valores posibles son'l1'
,'l2'
,'elasticnet'
y'none'
. La regularización es crucial para evitar el sobreajuste y mejorar la generalización del modelo.'l1'
: Utiliza la norma L1 para la penalización, lo que puede resultar en coeficientes esparcidos, es decir, muchos coeficientes serán cero. Esto equivale a una selección automática de características.'l2'
: Aplica la norma L2, que reduce la magnitud de los coeficientes pero no los anula completamente.'elasticnet'
: Combina L1 y L2 mediante el parámetrol1_ratio
.'none'
: Desactiva la regularización, lo cual puede ser arriesgado si el modelo es propenso al sobreajuste.
dual
: Indica si se debe resolver el problema dual o primal. Este parámetro es relevante cuando se utiliza el solver'liblinear'
y la penalización'l2'
. Se recomiendadual=False
para problemas con muchas muestras y pocas características, ydual=True
en el caso contrario.tol
: Establece la tolerancia para el criterio de parada. Es un valor de tolerancia que determina cuándo el algoritmo ha convergido. Valores más pequeños pueden conducir a soluciones más precisas pero requieren más tiempo de cómputo.C
: Representa el inverso de la fuerza de regularización. Un valor pequeño deC
implica una regularización más fuerte. Es importante ajustar este parámetro mediante validación cruzada para encontrar el equilibrio adecuado entre ajuste y generalización.fit_intercept
: Especifica si se debe incluir un término independiente o intercepto en el modelo. Por defecto esTrue
. Si los datos ya están centrados, puede establecerse enFalse
para simplificar el modelo.intercept_scaling
: Utilizado solo cuandosolver='liblinear'
yfit_intercept=True
. Este parámetro multiplica al término independiente. Generalmente, el valor por defecto de1
es adecuado, pero puede ajustarse si se requiere.class_weight
: Permite asignar pesos a las clases para manejar conjuntos de datos desbalanceados. Puede ser un diccionario con el formato{clase: peso}
o el valor'balanced'
, que ajusta los pesos inversamente proporcionales a las frecuencias de las clases.random_state
: Controla la aleatoriedad en la inicialización y permite reproducir los resultados. Es especialmente relevante cuando se utilizan solvers como'sag'
,'saga'
o al manejar pesos de clase.solver
: Especifica el algoritmo utilizado para encontrar los coeficientes óptimos. Los solvers disponibles son'newton-cg'
,'lbfgs'
,'liblinear'
,'sag'
y'saga'
.'newton-cg'
,'lbfgs'
y'sag'
: Soportan únicamente la penalización'l2'
.'liblinear'
: Soporta'l1'
y'l2'
, y es adecuado para conjuntos de datos pequeños.'saga'
: Soporta'l1'
,'l2'
,'elasticnet'
y es eficiente para grandes conjuntos de datos.
La elección del solver depende del tamaño del conjunto de datos y de la penalización deseada.
max_iter
: Especifica el número máximo de iteraciones que el solver realizará. Si el algoritmo no converge, es posible aumentar este valor. Por ejemplo:
modelo = LogisticRegression(max_iter=200)
multi_class
: Determina cómo se maneja la clasificación multiclase. Los valores posibles son'auto'
,'ovr'
(one-vs-rest) y'multinomial'
.'ovr'
: Ajusta un modelo binario por cada clase.'multinomial'
: Ajusta un modelo considerando todas las clases simultáneamente.'auto'
: Selecciona automáticamente'ovr'
o'multinomial'
dependiendo del solver.
verbose
: Controla el nivel de verborrea o mensajes de estado durante el ajuste del modelo. Valores mayores ofrecen más información. Es útil para depurar o entender el proceso de convergencia.warm_start
: Si se establece enTrue
, reutiliza la solución previa como inicialización para el próximo ajuste. Esto puede acelerar la convergencia cuando se está ajustando un modelo varias veces sobre datos similares.n_jobs
: Define el número de núcleos de CPU a utilizar para paralelizar el cálculo, solo aplicable cuandomulti_class='ovr'
y en algunos solvers. Un valor de-1
utiliza todos los núcleos disponibles.l1_ratio
: Es relevante cuandopenalty='elasticnet'
, y representa el parámetro de mezcla entre L1 y L2. Un valor de0
equivale a L2, y un valor de1
equivale a L1. Por ejemplo:
modelo = LogisticRegression(penalty='elasticnet', solver='saga', l1_ratio=0.5)
Este ejemplo aplica una regularización Elastic Net equilibrando las penalizaciones L1 y L2.
Ejemplo práctico
A continuación, se muestra un ejemplo práctico que ilustra el uso de algunos de estos parámetros:
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# Carga de datos
X, y = load_iris(return_X_y=True)
# División de datos
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, stratify=y)
# Creación del modelo con parámetros personalizados
modelo = LogisticRegression(
penalty='l1',
solver='saga',
C=0.1,
max_iter=1000,
class_weight='balanced', # Manejo de desbalanceo
random_state=42
)
# Entrenamiento del modelo
modelo.fit(X_train, y_train)
# Evaluación
score = modelo.score(X_test, y_test)
print(f'Precisión del modelo: {score:.2f}')
En este ejemplo, se utiliza la penalización 'l1'
con el solver 'saga'
, que es compatible con modelos multiclase y regularización L1. El parámetro C=0.1
indica una regularización más fuerte, lo que puede ayudar a prevenir el sobreajuste en problemas con pocos datos o muchas características. Se establece max_iter=1000
para asegurar la convergencia del modelo, y se maneja el desbalanceo de clases con class_weight='balanced'
. Además, la estratificación garantiza que la proporción de clases se mantenga en los conjuntos de entrenamiento y prueba.
Consideraciones adicionales
- Convergencia: Si el modelo no converge, es recomendable aumentar
max_iter
y ajustartol
para obtener una solución más precisa. - Escalado de datos: Para optimizar el rendimiento, es aconsejable escalar las características, especialmente cuando se utilizan penalizaciones L1 o Elastic Net.
- Selección del solver: La elección del solver puede afectar significativamente el tiempo de entrenamiento y la capacidad para manejar diferentes penalizaciones y conjuntos de datos.
Conocer y ajustar adecuadamente los parámetros de LogisticRegression
permite personalizar el modelo para adaptarse a distintos escenarios y mejorar su rendimiento en tareas de clasificación.
Interpretabilidad de la regresión logística para clasificación en scikit learn
La regresión logística es apreciada por su facilidad de interpretabilidad, ya que permite comprender cómo las variables independientes influyen en la probabilidad de que ocurra un evento. En scikit-learn, podemos acceder a los coeficientes del modelo y utilizarlos para interpretar el impacto de cada característica en la predicción.
Los coeficientes estimados se encuentran en el atributo coef_
del objeto LogisticRegression
. Este atributo es un array que contiene los coeficientes asociados a cada característica. Para una comprensión más detallada, es útil presentar estos coeficientes en un DataFrame de pandas junto con los nombres de las características:
import pandas as pd
# Supongamos que tenemos un modelo entrenado llamado 'modelo'
# Y una lista de nombres de características 'nombres_caracteristicas'
coeficientes = pd.DataFrame({
'Característica': nombres_caracteristicas,
'Coeficiente': modelo.coef_[0]
})
print(coeficientes)
Los coeficientes representan el impacto logarítmico de cada característica en la probabilidad de las clases. Sin embargo, para una interpretación más intuitiva, podemos calcular el odds ratio mediante la exponenciación de los coeficientes. Este valor indica cuánto cambia la razón de probabilidades por un incremento unitario en la característica:
import numpy as np
coeficientes['Odds Ratio'] = np.exp(coeficientes['Coeficiente'])
El odds ratio facilita la interpretación, ya que un valor mayor que uno indica que al aumentar la característica, también aumenta la probabilidad del evento. Por el contrario, un valor menor que uno sugiere que al aumentar la característica, disminuye la probabilidad del evento. Es esencial prestar atención al signo y al valor de los coeficientes para entender la relación entre las variables y la respuesta.
Además de los coeficientes, es útil analizar la significancia estadística de las características. Aunque scikit-learn no proporciona directamente los valores p, podemos utilizar la biblioteca statsmodels
para obtener un resumen estadístico más completo del modelo:
import statsmodels.api as sm
# Agregar el intercepto
X_entrenamiento_con_intercepto = sm.add_constant(X_entrenamiento)
# Ajustar el modelo con statsmodels
modelo_sm = sm.Logit(y_entrenamiento, X_entrenamiento_con_intercepto)
resultado = modelo_sm.fit()
# Resumen del modelo
print(resultado.summary())
El resumen obtenido muestra los valores p, los intervalos de confianza y otras métricas que ayudan a evaluar la significancia de cada coeficiente. Características con valores p pequeños son consideradas estadísticamente significativas en la predicción del modelo.
Otra herramienta para la interpretabilidad es la curva de probabilidad. Podemos visualizar cómo cambia la probabilidad predicha en función de una característica específica, manteniendo las demás constantes. Esto se logra generando un rango de valores para una característica y calculando las probabilidades correspondientes:
import matplotlib.pyplot as plt
import numpy as np
# Seleccionamos una característica
caracteristica = 'edad'
rango_valores = np.linspace(X[caracteristica].min(), X[caracteristica].max(), 100)
# Creamos un DataFrame con los valores medios para las otras características
X_promedio = pd.DataFrame(X_entrenamiento.mean()).T
X_promedio = X_promedio.loc[X_promedio.index.repeat(100)].reset_index(drop=True)
X_promedio[caracteristica] = rango_valores
# Calculamos las probabilidades
probabilidades = modelo.predict_proba(X_promedio)[:, 1]
# Gráfico
plt.plot(rango_valores, probabilidades)
plt.xlabel('Edad')
plt.ylabel('Probabilidad de evento')
plt.title('Probabilidad predicha en función de la edad')
plt.show()
La visualización anterior muestra la relación entre la edad y la probabilidad predicha, lo que facilita comprender el efecto de esta variable en el modelo. Esta técnica puede aplicarse a otras características para explorar sus influencias individuales.
Otra técnica avanzada es utilizar herramientas como SHAP (SHapley Additive exPlanations) para interpretar modelos de aprendizaje automático. SHAP proporciona valores de importancia para cada característica en una predicción específica, ayudando a explicar individualmente las predicciones:
import shap
# Crear el objeto explainer
explainer = shap.LinearExplainer(modelo, X_entrenamiento)
# Calcular los valores SHAP
shap_values = explainer.shap_values(X_prueba)
# Visualizar los valores SHAP para una instancia
shap.initjs()
shap.force_plot(explainer.expected_value, shap_values[0], X_prueba.iloc[0])
Los valores SHAP muestran cómo cada característica contribuye a la desviación de la predicción respecto al valor esperado. Esto es particularmente útil para justificar decisiones y cumplir con requisitos de transparencia en modelos predictivos.
Además, podemos generar un summary plot con SHAP para visualizar la importancia general de las características en el modelo. Esto permite identificar cuáles son las variables más influyentes en las predicciones globales:
# Summary plot
shap.summary_plot(shap_values, X_prueba)
Es importante recordar que la interpretabilidad de la regresión logística se basa en la relación lineal entre las variables independientes y el logit de la probabilidad. Por tanto, entender y examinar los coeficientes es fundamental para extraer conocimientos valiosos del modelo y tomar decisiones informadas.
Ejercicios de esta lección Clasificación con Regresión logística
Evalúa tus conocimientos de esta lección Clasificación con Regresión logística 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 logística y su aplicación en clasificación.
- Implementar modelos de regresión logística utilizando Scikit Learn.
- Realizar preprocesamiento de datos específico para mejorar el rendimiento del modelo.
- Ajustar y optimizar los parámetros de la clase
LogisticRegression
. - Interpretar y analizar los resultados del modelo para una toma de decisiones informada.