scikit-learn

ScikitLearn

Tutorial ScikitLearn: Selección de características

Scikit Learn: Selección de características para mejorar modelos de aprendizaje automático. Descubre métodos de filtros, wrappers y modelos en preprocesamiento de datos.

Aprende ScikitLearn GRATIS y certifícate

Importancia de la selección de características

La selección de características es un paso crucial en el preprocesamiento de datos que tiene un impacto significativo en el rendimiento de los modelos de aprendizaje automático. Al centrarse únicamente en las variables más relevantes, se mejora la eficiencia computacional, se reduce la complejidad del modelo y se minimiza el riesgo de sobreajuste.

En conjuntos de datos con un gran número de características, es común que algunas sean irrelevantes o redundantes. Estas características pueden introducir ruido y dificultar que el modelo aprenda patrones significativos. Además, un alto número de variables puede aumentar el tiempo de entrenamiento y complicar la interpretabilidad del modelo.

Por ejemplo, en aplicaciones como el procesamiento de imágenes o textos, los conjuntos de datos pueden tener miles de características. Aplicar técnicas de selección ayuda a identificar las variables más significativas, lo que conduce a modelos más simples y eficientes.

Consideremos un ejemplo práctico utilizando el conjunto de datos Breast Cancer Wisconsin para clasificar tumores como benignos o malignos. Este conjunto contiene 30 características. Primero, entrenaremos un modelo utilizando todas las características disponibles:

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score

# Cargar el conjunto de datos
datos = load_breast_cancer()
X = datos.data
y = datos.target

# Dividir los datos en conjuntos de entrenamiento y prueba
X_entreno, X_prueba, y_entreno, y_prueba = train_test_split(X, y, test_size=0.2, random_state=42)

# Crear y entrenar el modelo
modelo = SVC(kernel='linear', random_state=42)
modelo.fit(X_entreno, y_entreno)

# Realizar predicciones y evaluar el modelo
predicciones = modelo.predict(X_prueba)
exactitud = accuracy_score(y_prueba, predicciones)
print(f"Exactitud con todas las características: {exactitud:.2f}")

Ahora, aplicaremos SelectKBest para seleccionar las 10 características más relevantes utilizando la prueba chi-cuadrado:

from sklearn.feature_selection import SelectKBest, chi2

# Aplicar SelectKBest para la selección de características
selector = SelectKBest(score_func=chi2, k=10)
X_nuevo = selector.fit_transform(X, y)

# Dividir los datos seleccionados
X_entreno_sel, X_prueba_sel, _, _ = train_test_split(X_nuevo, y, test_size=0.2, random_state=42)

# Entrenar el modelo con las características seleccionadas
modelo_sel = SVC(kernel='linear', random_state=42)
modelo_sel.fit(X_entreno_sel, y_entreno)

# Realizar predicciones y evaluar el modelo
predicciones_sel = modelo_sel.predict(X_prueba_sel)
exactitud_sel = accuracy_score(y_prueba, predicciones_sel)
print(f"Exactitud con características seleccionadas: {exactitud_sel:.2f}")

Al comparar ambas exactitudes, es posible observar que el modelo con menos características logra un rendimiento similar al original. Esto indica que las características eliminadas no aportaban información relevante y su exclusión simplifica el modelo sin sacrificar precisión. Además, con menos variables, el modelo es más interpretativo, facilitando la comprensión de cómo cada característica influye en la predicción.

La selección de características también es esencial para manejar el problema de la maldición de la dimensionalidad, donde un exceso de variables puede dificultar el aprendizaje del modelo debido al espacio de búsqueda aumentado. Al reducir la dimensionalidad, se mejora la generalización del modelo a nuevos datos.

Las principales ventajas de la selección de características son:

  • Reducción del sobreajuste: al eliminar características irrelevantes, se disminuye el riesgo de ajustar el modelo demasiado al conjunto de entrenamiento.
  • Mejora de la precisión: centrándose en las variables más importantes, el modelo puede hacer predicciones más precisas.
  • Aumento de la eficiencia: menos características implican tiempos de entrenamiento y procesamiento más rápidos.
  • Facilitación de la interpretabilidad: con menos variables, es más sencillo analizar y comprender el comportamiento del modelo.

En conclusión, incorporar técnicas de selección de características es fundamental para desarrollar modelos de aprendizaje automático más eficientes y robustos. Herramientas como SelectKBest, Recursive Feature Elimination (RFE) o los métodos basados en la importancia de características proporcionan formas efectivas de identificar y seleccionar las variables más relevantes en Scikit Learn.

Métodos basados en filtros

Los métodos basados en filtros son técnicas de selección de características que evalúan la relevancia de cada variable de forma independiente del modelo de aprendizaje. Estas técnicas utilizan criterios estadísticos para medir la asociación o dependencia entre las características y la variable objetivo, permitiendo identificar y eliminar aquellas que son irrelevantes o redundantes.

Una ventaja clave de los métodos de filtro es su eficiencia computacional, ya que procesan las características sin necesidad de entrenar un modelo. Esto los hace especialmente adecuados para conjuntos de datos con un gran número de variables.

En Scikit Learn, se dispone de varias funciones para aplicar métodos basados en filtros:

  • SelectKBest: selecciona las k características con las mejores puntuaciones según una función de evaluación.
  • SelectPercentile: selecciona el porcentaje más alto de características basándose en las puntuaciones.

Funciones de evaluación

Las funciones de evaluación son fundamentales en los métodos basados en filtros. Determinan cómo se mide la relevancia de cada característica. Algunas de las funciones disponibles en Scikit Learn son:

  • Chi-cuadrado (chi2): mide la dependencia entre variables categóricas.
  • ANOVA (f_classif): analiza la varianza para características numéricas en problemas de clasificación.
  • Información mutua (mutual_info_classif y mutual_info_regression): estima la dependencia mutua entre variables.

Ejemplo práctico: Selección de características con Chi-cuadrado

Supongamos que tenemos un conjunto de datos para un problema de clasificación y queremos seleccionar las características más relevantes utilizando la prueba chi-cuadrado.

import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import SelectKBest, chi2

# Cargar el conjunto de datos
datos = load_breast_cancer()
X = datos.data
y = datos.target
nombres_caracteristicas = datos.feature_names

# Convertir a DataFrame para facilitar la manipulación
X_df = pd.DataFrame(X, columns=nombres_caracteristicas)

# Aplicar SelectKBest con chi-cuadrado
selector = SelectKBest(score_func=chi2, k=5)
X_nuevo = selector.fit_transform(X_df, y)

# Obtener las características seleccionadas
mascara = selector.get_support()
caracteristicas_seleccionadas = X_df.columns[mascara]
print("Características seleccionadas:", caracteristicas_seleccionadas.tolist())

En este ejemplo, utilizamos SelectKBest con la función de puntuación chi2 para seleccionar las 5 características más relevantes. La variable caracteristicas_seleccionadas contiene los nombres de estas características.

Interpretación de los resultados

La función chi-cuadrado es adecuada para características no negativas y mide la dependencia entre variables categóricas. Es importante asegurarse de que los datos cumplen con los requisitos de la prueba. Si las características son negativas o continuas, puede ser necesario escalarlas o utilizar otra función de evaluación.

Utilizando ANOVA para características numéricas

Para problemas de clasificación con características numéricas, la prueba ANOVA es una elección adecuada. A continuación, se muestra cómo aplicarla:

from sklearn.feature_selection import SelectKBest, f_classif

# Aplicar SelectKBest con f_classif
selector = SelectKBest(score_func=f_classif, k=5)
X_nuevo = selector.fit_transform(X_df, y)

# Obtener las características seleccionadas
mascara = selector.get_support()
caracteristicas_seleccionadas = X_df.columns[mascara]
print("Características seleccionadas:", caracteristicas_seleccionadas.tolist())

La función f_classif calcula el estadístico F de ANOVA entre cada característica y la variable objetivo, identificando aquellas con mayor poder discriminatorio.

Información mutua para relación no lineal

Cuando se sospecha que la relación entre las características y la variable objetivo no es lineal, la información mutua es una herramienta eficaz:

from sklearn.feature_selection import SelectKBest, mutual_info_classif

# Aplicar SelectKBest con mutual_info_classif
selector = SelectKBest(score_func=mutual_info_classif, k=5)
X_nuevo = selector.fit_transform(X_df, y)

# Obtener las características seleccionadas
mascara = selector.get_support()
caracteristicas_seleccionadas = X_df.columns[mascara]
print("Características seleccionadas:", caracteristicas_seleccionadas.tolist())

La función mutual_info_classif estima la dependencia mutua entre cada característica y la variable objetivo sin asumir ninguna forma paramétrica.

Selección basada en percentiles

Si se prefiere seleccionar características basándose en un porcentaje, se puede utilizar SelectPercentile:

from sklearn.feature_selection import SelectPercentile, f_classif

# Seleccionar el 20% superior de características
selector = SelectPercentile(score_func=f_classif, percentile=20)
X_nuevo = selector.fit_transform(X_df, y)

# Obtener las características seleccionadas
mascara = selector.get_support()
caracteristicas_seleccionadas = X_df.columns[mascara]
print("Características seleccionadas:", caracteristicas_seleccionadas.tolist())

Este enfoque es útil cuando no se conoce de antemano el número óptimo de características, pero se desea limitar la selección a un porcentaje específico.

Visualización de las puntuaciones

Es beneficioso visualizar las puntuaciones asignadas a cada característica para comprender su relevancia:

import matplotlib.pyplot as plt

# Calcular las puntuaciones de ANOVA
puntajes, _ = f_classif(X_df, y)

# Crear un DataFrame con las puntuaciones
df_puntajes = pd.DataFrame({'Característica': X_df.columns, 'Puntaje': puntajes})

# Ordenar por puntaje descendente
df_puntajes = df_puntajes.sort_values('Puntaje', ascending=False)

# Visualizar las puntuaciones
plt.figure(figsize=(10, 6))
plt.bar(df_puntajes['Característica'][:10], df_puntajes['Puntaje'][:10])
plt.xticks(rotation=90)
plt.xlabel('Características')
plt.ylabel('Puntaje F')
plt.title('Puntuaciones ANOVA de las Características')
plt.show()

Esta gráfica de barras muestra las 10 características con mayor puntaje según la prueba ANOVA, facilitando la interpretación de su importancia relativa.

Consideraciones al utilizar métodos de filtro

  • Independencia del modelo: Los métodos basados en filtros no consideran las interacciones entre las características, ya que evalúan cada variable de forma individual.
  • Rápida evaluación: Debido a su simplicidad, son adecuados para una preselección inicial de características en conjuntos de datos de alta dimensionalidad.
  • Complementariedad: A menudo se combinan con otros métodos, como los basados en wrapper o basados en modelos, para mejorar la selección final.

Aplicación en problemas de regresión

Para problemas de regresión, se utilizan funciones de evaluación adecuadas como f_regression y mutual_info_regression:

from sklearn.feature_selection import SelectKBest, f_regression
from sklearn.datasets import load_boston

# Cargar el conjunto de datos
datos = load_boston()
X = datos.data
y = datos.target
nombres_caracteristicas = datos.feature_names

X_df = pd.DataFrame(X, columns=nombres_caracteristicas)

# Aplicar SelectKBest con f_regression
selector = SelectKBest(score_func=f_regression, k=5)
X_nuevo = selector.fit_transform(X_df, y)

# Obtener las características seleccionadas
mascara = selector.get_support()
caracteristicas_seleccionadas = X_df.columns[mascara]
print("Características seleccionadas:", caracteristicas_seleccionadas.tolist())

En este caso, utilizamos la prueba F para regresión, identificando las características numéricas que mejor explican la variabilidad de la variable objetivo.

Limitaciones de los métodos basados en filtros

  • Ignoran la Interacción entre características: Al evaluar las variables individualmente, pueden pasar por alto combinaciones que son relevantes solo cuando se consideran conjuntamente.
  • No Consideran el modelo final: La selección no está optimizada para el modelo específico que se utilizará posteriormente, lo que puede afectar al rendimiento.

Mejor práctica

Es recomendable utilizar los métodos basados en filtros como primer paso en el proceso de selección de características. Posteriormente, se pueden aplicar métodos más avanzados para refinar la selección y adaptar mejor el conjunto de características al modelo elegido.

Métodos basados en wrapper

Los métodos basados en wrapper son técnicas de selección de características que evalúan iterativamente diferentes subconjuntos de variables para identificar aquellas que optimizan el rendimiento de un modelo específico de aprendizaje automático. A diferencia de los métodos basados en filtros, que seleccionan características en función de medidas estadísticas generales, los wrappers utilizan un modelo predictivo para evaluar la calidad de los distintos subconjuntos de características.

El enfoque principal de los métodos wrapper es combinar la selección de características con el proceso de entrenamiento del modelo. Esto significa que consideran las interacciones entre características y cómo afectan al rendimiento del modelo. Aunque este método puede ser computacionalmente intensivo, a menudo produce mejores resultados en términos de precisión y generalización del modelo.

En Scikit Learn, se proporcionan varias herramientas para implementar métodos basados en wrapper, como la Eliminación Recursiva de Características (RFE) y la Selección de Características Secuencial. Estas técnicas permiten integrar fácilmente la selección de características con los estimadores existentes, proporcionando un marco robusto para mejorar los modelos.

La Eliminación Recursiva de Características (RFE) es un método que selecciona características eliminando, de forma iterativa, las menos importantes según un estimador base. El proceso comienza entrenando el modelo con todas las características y, en cada iteración, se elimina el conjunto de características menos relevantes. Este procedimiento continúa hasta que se alcanza el número deseado de características.

A continuación, se presenta un ejemplo práctico utilizando RFE con un clasificador SVC (Support Vector Classifier) en el conjunto de datos Breast Cancer Wisconsin:

import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import RFE
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Cargar el conjunto de datos
datos = load_breast_cancer()
X = datos.data
y = datos.target
nombres_caracteristicas = datos.feature_names

# Dividir los datos en conjuntos de entrenamiento y prueba
X_entreno, X_prueba, y_entreno, y_prueba = train_test_split(X, y, test_size=0.2, random_state=42)

# Crear el estimador base
modelo = SVC(kernel='linear', random_state=42)

# Configurar RFE para seleccionar 5 características
selector = RFE(estimator=modelo, n_features_to_select=5, step=1)

# Ajustar RFE al conjunto de entrenamiento
selector.fit(X_entreno, y_entreno)

# Transformar conjuntos de entrenamiento y prueba
X_entreno_rfe = selector.transform(X_entreno)
X_prueba_rfe = selector.transform(X_prueba)

# Entrenar el modelo con las características seleccionadas
modelo.fit(X_entreno_rfe, y_entreno)

# Realizar predicciones y evaluar el modelo
predicciones = modelo.predict(X_prueba_rfe)
exactitud = accuracy_score(y_prueba, predicciones)
print(f"Exactitud con RFE: {exactitud:.2f}")

# Mostrar las características seleccionadas
caracteristicas_seleccionadas = nombres_caracteristicas[selector.support_]
print("Características seleccionadas:", caracteristicas_seleccionadas)

Salida:

En este ejemplo, se utiliza RFE para seleccionar las 5 características más significativas según el modelo SVC con kernel lineal. Después de ajustar el selector, se transforman los conjuntos de entrenamiento y prueba para incluir solo las características seleccionadas. Finalmente, se entrena el modelo y se evalúa su rendimiento en el conjunto de prueba.

La propiedad support_ del objeto selector devuelve un arreglo booleano que indica qué características han sido seleccionadas. Esto permite identificar cuáles son las variables más relevantes para el modelo, facilitando la interpretación y reduciendo la complejidad.

Otra variante es RFECV (Eliminación Recursiva de Características con Validación Cruzada), que extiende RFE al incorporar validación cruzada para determinar automáticamente el número óptimo de características. Esto ayuda a evitar la selección de un número excesivo o insuficiente de características, mejorando la generalización del modelo.

from sklearn.feature_selection import RFECV

# Configurar RFECV con validación cruzada de 5 particiones
selector_rfecv = RFECV(estimator=modelo, step=1, cv=5, scoring='accuracy')

# Ajustar RFECV al conjunto de entrenamiento
selector_rfecv.fit(X_entreno, y_entreno)

# Transformar conjuntos de entrenamiento y prueba
X_entreno_rfecv = selector_rfecv.transform(X_entreno)
X_prueba_rfecv = selector_rfecv.transform(X_prueba)

# Entrenar el modelo con las características seleccionadas
modelo.fit(X_entreno_rfecv, y_entreno)

# Realizar predicciones y evaluar el modelo
predicciones_rfecv = modelo.predict(X_prueba_rfecv)
exactitud_rfecv = accuracy_score(y_prueba, predicciones_rfecv)
print(f"Exactitud con RFECV: {exactitud_rfecv:.2f}")

# Mostrar el número óptimo de características y las seleccionadas
print(f"Número óptimo de características: {selector_rfecv.n_features_}")
caracteristicas_seleccionadas_rfecv = nombres_caracteristicas[selector_rfecv.support_]
print("Características seleccionadas por RFECV:", caracteristicas_seleccionadas_rfecv)

En este caso, RFECV selecciona automáticamente el número de características que maximiza la exactitud del modelo utilizando validación cruzada. Esto proporciona una selección más ajustada y potencialmente mejora el rendimiento en datos no vistos.

La Selección de Características Secuencial es otro método basado en wrapper que incorpora estrategias forward (hacia adelante) y backward (hacia atrás). En la estrategia forward, el algoritmo comienza sin características y agrega iterativamente la que más mejora el modelo. En la estrategia backward, comienza con todas las características y elimina iterativamente la que menos impacta en el rendimiento.

A continuación, se muestra un ejemplo utilizando la Selección de Características Secuencial con estrategia forward:

from sklearn.feature_selection import SequentialFeatureSelector

# Crear el selector secuencial con estrategia forward
selector_secuencial = SequentialFeatureSelector(
    estimator=modelo,
    n_features_to_select=5,
    direction='forward',
    scoring='accuracy',
    cv=5
)

# Ajustar el selector al conjunto de entrenamiento
selector_secuencial.fit(X_entreno, y_entreno)

# Transformar conjuntos de entrenamiento y prueba
X_entreno_sfs = selector_secuencial.transform(X_entreno)
X_prueba_sfs = selector_secuencial.transform(X_prueba)

# Entrenar el modelo con las características seleccionadas
modelo.fit(X_entreno_sfs, y_entreno)

# Realizar predicciones y evaluar el modelo
predicciones_sfs = modelo.predict(X_prueba_sfs)
exactitud_sfs = accuracy_score(y_prueba, predicciones_sfs)
print(f"Exactitud con Selección Secuencial: {exactitud_sfs:.2f}")

# Mostrar las características seleccionadas
caracteristicas_seleccionadas_sfs = nombres_caracteristicas[selector_secuencial.get_support()]
print("Características seleccionadas por Selección Secuencial:", caracteristicas_seleccionadas_sfs)

En este ejemplo, la Selección de Características Secuencial agrega características una a una, evaluando en cada paso cuál contribuye más al aumento de la exactitud del modelo. La validación cruzada garantiza que la selección no esté sesgada hacia el conjunto de entrenamiento, promoviendo una mejor generalización.

Los métodos basados en wrapper ofrecen la ventaja de considerar las interacciones entre características y su impacto directo en el modelo. Sin embargo, pueden ser computacionalmente costosos, especialmente con conjuntos de datos de alta dimensionalidad. Además, existe el riesgo de sobreajuste si el modelo se ajusta demasiado al conjunto de entrenamiento durante el proceso de selección.

Es común combinar métodos de filtro y wrapper para aprovechar las ventajas de ambos. Por ejemplo, se puede utilizar un método de filtro para reducir inicialmente el número de características y luego aplicar un método wrapper para refinar la selección. Esta combinación puede equilibrar la eficiencia computacional y la eficacia en la selección de características.

Al utilizar métodos basados en wrapper, es esencial considerar el equilibrio entre el rendimiento del modelo y el tiempo de cómputo requerido. La selección adecuada de características no solo mejora la precisión del modelo sino que también puede reducir la complejidad y mejorar la interpretabilidad, facilitando la implementación en entornos de producción.

Métodos basados en modelos

Los métodos basados en modelos aprovechan las propiedades intrínsecas de ciertos algoritmos que pueden evaluar la importancia de las características durante el proceso de entrenamiento. Estos métodos utilizan modelos que asignan pesos o coeficientes a las variables, permitiendo identificar y seleccionar las más relevantes para la predicción.

En Scikit Learn, la clase SelectFromModel facilita la selección de características basándose en la importancia estimada por un modelo entrenado. Esta técnica es especialmente útil con estimadores que proporcionan atributos como coef_ para modelos lineales o feature_importances_ para modelos de árboles.

Ejemplo práctico con regresión Lasso

La regresión Lasso es un modelo lineal que utiliza regularización L1 para penalizar los coeficientes de las características menos importantes, reduciéndolos a cero. Esto permite realizar una selección implícita de variables durante el entrenamiento.

A continuación, se muestra cómo aplicar SelectFromModel con un modelo Lasso para seleccionar características importantes en un conjunto de datos de regresión:

import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import Lasso
from sklearn.feature_selection import SelectFromModel
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# Cargar el conjunto de datos
datos = fetch_california_housing(as_frame=True)
X = datos.data
y = datos.target

# Dividir los datos en conjuntos de entrenamiento y prueba
X_entreno, X_prueba, y_entreno, y_prueba = train_test_split(X, y, test_size=0.2, random_state=42)

# Crear y entrenar el modelo Lasso
modelo_lasso = Lasso(alpha=0.1, random_state=42, max_iter=10000)
modelo_lasso.fit(X_entreno, y_entreno)

# Convertir los datos a NumPy para evitar conflictos de nombres
X_entreno_np = X_entreno.to_numpy()
X_prueba_np = X_prueba.to_numpy()

# Utilizar SelectFromModel para seleccionar características
selector = SelectFromModel(modelo_lasso, prefit=True)
X_entreno_sel = selector.transform(X_entreno_np)
X_prueba_sel = selector.transform(X_prueba_np)

# Asegurarse de mantener las características seleccionadas con nombres
caracteristicas_seleccionadas = X.columns[selector.get_support()]

# Entrenar nuevamente el modelo con las características seleccionadas
modelo_lasso_sel = Lasso(alpha=0.1, random_state=42, max_iter=10000)
modelo_lasso_sel.fit(X_entreno_sel, y_entreno)

# Evaluar el modelo original y el modelo con características seleccionadas
predicciones_original = modelo_lasso.predict(X_prueba)
predicciones_sel = modelo_lasso_sel.predict(X_prueba_sel)
rmse_original = np.sqrt(mean_squared_error(y_prueba, predicciones_original))
rmse_sel = np.sqrt(mean_squared_error(y_prueba, predicciones_sel))
print(f"RMSE Modelo Original: {rmse_original:.2f}")
print(f"RMSE Modelo Seleccionado: {rmse_sel:.2f}")

# Mostrar las características seleccionadas
print("Características seleccionadas:", list(caracteristicas_seleccionadas))

En este ejemplo, después de entrenar el modelo Lasso inicial, SelectFromModel identifica y selecciona automáticamente las características con coeficientes no nulos. El modelo resultante es más sencillo y puede tener un rendimiento similar o incluso mejorado, debido a la reducción de variables irrelevantes.

Uso de modelos de árbol con Feature Importances

Los modelos basados en árboles, como Random Forests y Gradient Boosting, calculan la importancia de las características en función de la reducción del criterio de impureza (por ejemplo, la impureza de Gini o la entropía). Estas importancias pueden utilizarse para realizar una selección de características.

A continuación, se presenta un ejemplo utilizando RandomForestClassifier en un problema de clasificación:

import numpy as np
from sklearn.datasets import load_wine
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import SelectFromModel
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Cargar el conjunto de datos
datos = load_wine()
X = datos.data
y = datos.target
nombres_caracteristicas = datos.feature_names

# Dividir los datos en conjuntos de entrenamiento y prueba
X_entreno, X_prueba, y_entreno, y_prueba = train_test_split(X, y, test_size=0.3, random_state=42)

# Crear y entrenar el modelo Random Forest
modelo_rf = RandomForestClassifier(n_estimators=100, random_state=42)
modelo_rf.fit(X_entreno, y_entreno)

# Utilizar SelectFromModel para seleccionar características
importancia_minima = np.mean(modelo_rf.feature_importances_)
selector = SelectFromModel(modelo_rf, threshold=importancia_minima, prefit=True)
X_entreno_sel = selector.transform(X_entreno)
X_prueba_sel = selector.transform(X_prueba)

# Entrenar nuevamente el modelo con las características seleccionadas
modelo_rf_sel = RandomForestClassifier(n_estimators=100, random_state=42)
modelo_rf_sel.fit(X_entreno_sel, y_entreno)

# Evaluar el modelo original y el modelo con características seleccionadas
predicciones_original = modelo_rf.predict(X_prueba)
predicciones_sel = modelo_rf_sel.predict(X_prueba_sel)
exactitud_original = accuracy_score(y_prueba, predicciones_original)
exactitud_sel = accuracy_score(y_prueba, predicciones_sel)
print(f"Exactitud Modelo Original: {exactitud_original:.2f}")
print(f"Exactitud Modelo Seleccionado: {exactitud_sel:.2f}")

# Mostrar las características seleccionadas
caracteristicas_seleccionadas = np.array(nombres_caracteristicas)[selector.get_support()]
print("Características seleccionadas:", list(caracteristicas_seleccionadas))

Salida: 

En este caso, SelectFromModel utiliza las importancias de las características calculadas por el modelo Random Forest para seleccionar las variables que contribuyen más a la predicción. Se define un umbral basado en el valor medio de las importancias para filtrar las características menos relevantes.

Personalización del umbral de selección

El parámetro threshold en SelectFromModel permite ajustar el criterio de selección. Puede definirse como un número fijo, una cadena relativa (por ejemplo, "1.5*mean") o dejarse en None para utilizar el valor predeterminado. Ajustar este valor es fundamental para controlar el número de características seleccionadas.

Ejemplo con umbral personalizado:

# Establecer un umbral personalizado
selector_custom = SelectFromModel(modelo_rf, threshold="1.25*mean", prefit=True)
X_entreno_sel_custom = selector_custom.transform(X_entreno)
X_prueba_sel_custom = selector_custom.transform(X_prueba)

# Entrenar y evaluar el modelo
modelo_rf_sel_custom = RandomForestClassifier(n_estimators=100, random_state=42)
modelo_rf_sel_custom.fit(X_entreno_sel_custom, y_entreno)
predicciones_sel_custom = modelo_rf_sel_custom.predict(X_prueba_sel_custom)
exactitud_sel_custom = accuracy_score(y_prueba, predicciones_sel_custom)
print(f"Exactitud con Umbral Personalizado: {exactitud_sel_custom:.2f}")

Al incrementar el umbral, se seleccionan solo las características con mayor importancia relativa, lo que puede conducir a modelos más simplificados. Es esencial evaluar el impacto de este ajuste en el rendimiento del modelo.

Modelos lineales con regularización L1

Además de Lasso, otros modelos lineales compatibles con penalización L1 pueden utilizarse para la selección de características, como Logistic Regression para problemas de clasificación.

Ejemplo con Logistic Regression:

from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import SelectFromModel
from sklearn.metrics import accuracy_score
import numpy as np

# Crear y entrenar el modelo Logistic Regression con penalización L1
modelo_logistic = LogisticRegression(penalty='l1', solver='liblinear', C=1.0, random_state=42)
modelo_logistic.fit(X_entreno, y_entreno)

# Utilizar SelectFromModel para seleccionar características
selector_logistic = SelectFromModel(modelo_logistic, prefit=True)
X_entreno_sel_logistic = selector_logistic.transform(X_entreno)
X_prueba_sel_logistic = selector_logistic.transform(X_prueba)

# Entrenar y evaluar el modelo
modelo_logistic_sel = LogisticRegression(penalty='l1', solver='liblinear', C=1.0, random_state=42)
modelo_logistic_sel.fit(X_entreno_sel_logistic, y_entreno)
predicciones_logistic_sel = modelo_logistic_sel.predict(X_prueba_sel_logistic)
exactitud_logistic_sel = accuracy_score(y_prueba, predicciones_logistic_sel)
print(f"Exactitud Modelo Logistic Regression Seleccionado: {exactitud_logistic_sel:.2f}")

# Mostrar las características seleccionadas
caracteristicas_seleccionadas_logistic = np.array(nombres_caracteristicas)[selector_logistic.get_support()]
print("Características seleccionadas por Logistic Regression:", list(caracteristicas_seleccionadas_logistic))

El uso de la penalización L1 en modelos lineales favorece la generación de coeficientes cero para características menos significativas, facilitando la selección automática mediante SelectFromModel. Es importante destacar que para aplicar la penalización L1 en LogisticRegression, se debe especificar el parámetro solver adecuado, como 'liblinear' o 'saga'.

Consideraciones sobre la escalabilidad

Los métodos basados en modelos son generalmente más eficientes que los métodos wrapper, ya que requieren entrenar el modelo solo una vez. Sin embargo, es fundamental seleccionar un estimador apropiado que sea capaz de proporcionar medidas de importancia de características.

Además, es recomendable normalizar o estandarizar los datos cuando se utilizan modelos sensibles a la escala de las variables, como los modelos lineales. Esto garantiza que las penalizaciones y los coeficientes sean comparables entre características.

Ejemplo de estandarización:

from sklearn.preprocessing import StandardScaler

# Estandarizar las características
escalador = StandardScaler()
X_entreno_escalado = escalador.fit_transform(X_entreno)
X_prueba_escalado = escalador.transform(X_prueba)

# Entrenar el modelo Lasso con datos escalados
modelo_lasso_escalado = Lasso(alpha=0.1, random_state=42)
modelo_lasso_escalado.fit(X_entreno_escalado, y_entreno)

# Seleccionar características
selector_escalado = SelectFromModel(modelo_lasso_escalado, prefit=True)
X_entreno_sel_escalado = selector_escalado.transform(X_entreno_escalado)
X_prueba_sel_escalado = selector_escalado.transform(X_prueba_escalado)

# Evaluar el modelo
modelo_lasso_sel_escalado = Lasso(alpha=0.1, random_state=42)
modelo_lasso_sel_escalado.fit(X_entreno_sel_escalado, y_entreno)
predicciones_sel_escalado = modelo_lasso_sel_escalado.predict(X_prueba_sel_escalado)
rmse_sel_escalado = np.sqrt(mean_squared_error(y_prueba, predicciones_sel_escalado))
print(f"RMSE Modelo Lasso Seleccionado con Datos Escalados: {rmse_sel_escalado:.2f}")

La estandarización con StandardScaler centra los datos en torno a cero y los escala a una varianza unitaria, lo cual es crucial para modelos que dependen del valor absoluto de los coeficientes.

Aplicación con modelos ensamblados

Los algoritmos de ensamblado, como Gradient Boosting, también ofrecen atributos de importancia de características que pueden explotarse para la selección:

from sklearn.ensemble import GradientBoostingClassifier

# Entrenar un modelo Gradient Boosting
modelo_gb = GradientBoostingClassifier(n_estimators=100, random_state=42)
modelo_gb.fit(X_entreno, y_entreno)

# Seleccionar características
selector_gb = SelectFromModel(modelo_gb, prefit=True, threshold="median")
X_entreno_sel_gb = selector_gb.transform(X_entreno)
X_prueba_sel_gb = selector_gb.transform(X_prueba)

# Evaluar el modelo
modelo_gb_sel = GradientBoostingClassifier(n_estimators=100, random_state=42)
modelo_gb_sel.fit(X_entreno_sel_gb, y_entreno)
predicciones_gb_sel = modelo_gb_sel.predict(X_prueba_sel_gb)
exactitud_gb_sel = accuracy_score(y_prueba, predicciones_gb_sel)
print(f"Exactitud Modelo Gradient Boosting Seleccionado: {exactitud_gb_sel:.2f}")

En este ejemplo, se utiliza el umbral "median" para seleccionar las características cuya importancia es superior a la mediana. Los modelos ensamblados pueden capturar relaciones no lineales y complejas entre las variables, lo que los hace valiosos para la selección de características en contextos más sofisticados.

Limitaciones y buenas prácticas

Si bien los métodos basados en modelos son efectivos, es importante considerar:

  • Dependencia del modelo: La selección de características está vinculada al estimador utilizado. Cambiar de modelo puede requerir reevaluar la selección.
  • Sobreajuste: Existe el riesgo de que el modelo se ajuste demasiado al conjunto de entrenamiento si no se valida adecuadamente.
  • Interpretabilidad: En modelos complejos, como los árboles ensamblados, las importancias pueden ser difíciles de interpretar en términos intuitivos.

Es recomendable combinar la validación cruzada al entrenar y evaluar los modelos para asegurar que la selección de características generaliza bien a nuevos datos.

Aprende ScikitLearn GRATIS online

Ejercicios de esta lección Selección de características

Evalúa tus conocimientos de esta lección Selección de características 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

scikit-learn

Introducción Y Entorno

Introducción E Instalación

scikit-learn

Introducción Y Entorno

Introducción Al Preprocesamiento De Datos

scikit-learn

Preprocesamiento De Datos

Identificación Y Tratamiento De Valores Faltantes

scikit-learn

Preprocesamiento De Datos

Escalado De Datos

scikit-learn

Preprocesamiento De Datos

Normalización De Datos

scikit-learn

Preprocesamiento De Datos

Codificación De Variables Categóricas

scikit-learn

Preprocesamiento De Datos

Ingeniería De Características

scikit-learn

Preprocesamiento De Datos

Selección De Características

scikit-learn

Preprocesamiento De Datos

Extracción De Características

scikit-learn

Preprocesamiento De Datos

Particionamiento De Datos

scikit-learn

Preprocesamiento De Datos

Preprocesamiento De Datos Desbalanceados

scikit-learn

Preprocesamiento De Datos

Introducción A La Regresión

scikit-learn

Regresión

Regresión Lineal

scikit-learn

Regresión

Regresión Knn Kneighborsregressor

scikit-learn

Regresión

Regresión Svm Con Svr

scikit-learn

Regresión

Regresión Con Árboles Decisiontreeregressor

scikit-learn

Regresión

Regresión Con Algoritmos De Conjunto

scikit-learn

Regresión

Introducción A La Clasificación

scikit-learn

Clasificación

Clasificación Con Regresión Logística

scikit-learn

Clasificación

Clasificación Knn Kneighborsclassifier

scikit-learn

Clasificación

Clasificación Svm Con Svc

scikit-learn

Clasificación

Clasificación Con Árboles Decisiontreeclassifier

scikit-learn

Clasificación

Clasificación Con Algoritmos De Conjunto

scikit-learn

Clasificación

Reducción De La Dimensionalidad Con Pca

scikit-learn

Aprendizaje No Supervisado

Clustering Con Kmeans

scikit-learn

Aprendizaje No Supervisado

Clustering Jerárquico

scikit-learn

Aprendizaje No Supervisado

Clustering De Densidad Con Dbscan

scikit-learn

Aprendizaje No Supervisado

Preprocesamiento De Textos Para Nlp

scikit-learn

Nlp

Representación De Texto Y Extracción De Características

scikit-learn

Nlp

Clasificación De Texto Con Scikit Learn

scikit-learn

Nlp

Análisis De Sentimiento

scikit-learn

Nlp

Técnicas Avanzadas De Extracción De Características

scikit-learn

Nlp

Introducción Al Análisis De Series Temporales

scikit-learn

Series Temporales

Preprocesamiento De Datos De Series Temporales

scikit-learn

Series Temporales

Ingeniería De Características Para Series Temporales

scikit-learn

Series Temporales

Transformación Y Escalado De Series Temporales

scikit-learn

Series Temporales

Validación Y Evaluación De Modelos En Series Temporales

scikit-learn

Series Temporales

Validación Y Evaluación De Modelos

scikit-learn

Validación De Modelos

Técnicas De Validación Cruzada

scikit-learn

Validación De Modelos

Métricas De Regresión

scikit-learn

Validación De Modelos

Métricas De Clasificación

scikit-learn

Validación De Modelos

Ajuste De Hiperparámetros

scikit-learn

Validación De Modelos

Introducción A Pipelines

scikit-learn

Pipelines Y Despliegue

Creación De Pipelines Básicos

scikit-learn

Pipelines Y Despliegue

Preprocesamiento De Datos Con Pipelines

scikit-learn

Pipelines Y Despliegue

Pipelines Y Validación Cruzada

scikit-learn

Pipelines Y Despliegue

Pipelines Con Columntransformer

scikit-learn

Pipelines Y Despliegue

Exportar E Importar Pipelines

scikit-learn

Pipelines Y Despliegue

Accede GRATIS a ScikitLearn y certifícate

Objetivos de aprendizaje de esta lección

  • Comprender la importancia de la selección de características en el preprocesamiento de datos.
  • Conocer los diferentes métodos de selección: basados en filtros, wrappers y modelos.
  • Aplicar técnicas de selección de características utilizando Scikit Learn.
  • Implementar ejemplos prácticos con SelectKBest, RFE y SelectFromModel.
  • Analizar el impacto de la selección de características en el rendimiento y la interpretabilidad de los modelos.
  • Mejorar la eficiencia y precisión de los algoritmos de aprendizaje automático reduciendo la dimensionalidad.