Aplicar métodos de envoltura en Python para la selección de características

A

Introducción

En el artículo anterior, estudiamos cómo podemos usar métodos de filtro para la selección de características para algoritmos de Machine Learning. Los métodos de filtro son útiles cuando desea seleccionar un conjunto genérico de características para todos los modelos de Machine Learning.

Sin embargo, en algunos escenarios, es posible que desee utilizar un algoritmo de Machine Learning específico para entrenar su modelo. En tales casos, las características seleccionadas mediante métodos de filtrado pueden no ser el conjunto de características más óptimo para ese algoritmo específico. Existe otra categoría de métodos de selección de características que seleccionan las características más óptimas para el algoritmo especificado. Tales métodos se llaman métodos de envoltura.

Métodos de envoltura para la selección de funciones

Los métodos de envoltura se basan en algoritmos de búsqueda codiciosos, ya que evalúan todas las combinaciones posibles de las funciones y seleccionan la combinación que produce el mejor resultado para un algoritmo de Machine Learning específico. Una desventaja de este enfoque es que probar todas las combinaciones posibles de las características puede ser computacionalmente muy costoso, particularmente si el conjunto de características es muy grande.

Como se dijo anteriormente, los métodos de envoltura pueden encontrar el mejor conjunto de características para un algoritmo específico; sin embargo, una desventaja es que este conjunto de características puede no ser óptimo para todos los demás algoritmos de Machine Learning.

Los métodos de envoltura para la selección de características se pueden dividir en tres categorías: Selección de funciones de avance, Paso hacia atrás en la selección de funciones y Selección exhaustiva de funciones. En este artículo, veremos cómo podemos implementar estos enfoques de selección de características en Python.

Selección de funciones de avance

En la primera fase de la selección de características del paso adelante, se evalúa el rendimiento del clasificador con respecto a cada característica. La función que funciona mejor se selecciona entre todas las funciones.

En el segundo paso, se prueba la primera función en combinación con todas las demás funciones. Se selecciona la combinación de dos características que producen el mejor rendimiento del algoritmo. El proceso continúa hasta que se selecciona el número especificado de funciones.

Implementemos la selección de funciones de avance en Python. Estaremos usando el Gestión de siniestros de BNP Paribas Cardif conjunto de datos para esta sección como hicimos en nuestro artículo anterior.

Para implementar la selección de características paso adelante, necesitamos convertir valores de características categóricas en valores de características numéricos. Sin embargo, en aras de la simplicidad, eliminaremos todas las columnas no categóricas de nuestros datos. También eliminaremos las columnas correlacionadas como hicimos en el artículo anterior para que tengamos un pequeño conjunto de funciones para procesar.

Preprocesamiento de datos

La siguiente secuencia de comandos importa el conjunto de datos y las bibliotecas necesarias, luego quita las columnas no numéricas del conjunto de datos y luego divide el conjunto de datos en conjuntos de entrenamiento y prueba. Finalmente, se eliminan todas las columnas con una correlación superior a 0,8. Eche un vistazo a este artículo para obtener una explicación detallada de este script:

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import VarianceThreshold

paribas_data = pd.read_csv(r"E:Datasetsparibas_data.csv", nrows=20000)
paribas_data.shape

num_colums = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
numerical_columns = list(paribas_data.select_dtypes(include=num_colums).columns)
paribas_data = paribas_data[numerical_columns]
paribas_data.shape

train_features, test_features, train_labels, test_labels = train_test_split(
    paribas_data.drop(labels=['target', 'ID'], axis=1),
    paribas_data['target'],
    test_size=0.2,
    random_state=41)

correlated_features = set()
correlation_matrix = paribas_data.corr()
for i in range(len(correlation_matrix .columns)):
    for j in range(i):
        if abs(correlation_matrix.iloc[i, j]) > 0.8:
            colname = correlation_matrix.columns[i]
            correlated_features.add(colname)


train_features.drop(labels=correlated_features, axis=1, inplace=True)
test_features.drop(labels=correlated_features, axis=1, inplace=True)

train_features.shape, test_features.shape

Implementación de la selección de funciones de avance en Python

Para seleccionar las características más óptimas, usaremos SequentialFeatureSelector función de la mlxtend biblioteca. La biblioteca se puede descargar ejecutando el siguiente comando en el símbolo del sistema de anaconda:

conda install -c conda-forge mlxtend

Usaremos el Clasificador de bosque aleatorio para encontrar los parámetros más óptimos. Los criterios de evaluación utilizados serán ROC-AUC. El siguiente script selecciona las 15 características de nuestro conjunto de datos que producen el mejor rendimiento para el clasificador de bosque aleatorio:

from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.metrics import roc_auc_score

from mlxtend.feature_selection import SequentialFeatureSelector

feature_selector = SequentialFeatureSelector(RandomForestClassifier(n_jobs=-1),
           k_features=15,
           forward=True,
           verbose=2,
           scoring='roc_auc',
           cv=4)

En el script de arriba pasamos el RandomForestClassifiercomo estimador de la SequentialFeatureSelector función. los k_features especifica el número de funciones a seleccionar. Puede configurar cualquier número de funciones aquí. los forward parámetro, si se establece en True, realiza la selección de funciones de avance. los verbose El parámetro se utiliza para registrar el progreso del selector de funciones, el scoring parámetro define los criterios de evaluación del desempeño y finalmente, cv se refiere a los pliegues de validación cruzada.

Creamos nuestro selector de funciones, ahora necesitamos llamar al fit en nuestro selector de funciones y páselo por los conjuntos de entrenamiento y prueba como se muestra a continuación:

features = feature_selector.fit(np.array(train_features.fillna(0)), train_labels)

Dependiendo del hardware de su sistema, la secuencia de comandos anterior puede tardar algún tiempo en ejecutarse. Una vez que el script anterior termine de ejecutarse, puede ejecutar el siguiente script para ver las 15 funciones seleccionadas:

filtered_features= train_features.columns[list(features.k_feature_idx_)]
filtered_features

En el resultado, debería ver las siguientes características:

Index(['v4', 'v10', 'v14', 'v15', 'v18', 'v20', 'v23', 'v34', 'v38', 'v42',
       'v50', 'v51', 'v69', 'v72', 'v129'],
      dtype="object")

Ahora, para ver el rendimiento de clasificación del algoritmo de bosque aleatorio utilizando estas 15 características, ejecute el siguiente script:

clf = RandomForestClassifier(n_estimators=100, random_state=41, max_depth=3)
clf.fit(train_features[filtered_features].fillna(0), train_labels)

train_pred = clf.predict_proba(train_features[filtered_features].fillna(0))
print('Accuracy on training set: {}'.format(roc_auc_score(train_labels, train_pred[:,1])))

test_pred = clf.predict_proba(test_features[filtered_features].fillna(0))
print('Accuracy on test set: {}'.format(roc_auc_score(test_labels, test_pred [:,1])))

En el script anterior, entrenamos nuestro algoritmo de bosque aleatorio en las 15 características que seleccionamos usando la selección de características de avance y luego evaluamos el rendimiento de nuestro algoritmo en los conjuntos de entrenamiento y prueba. En la salida, debería ver los siguientes resultados:

Accuracy on training set: 0.7072327148174093
Accuracy on test set: 0.7096973252804142

Puede ver que la precisión en los conjuntos de entrenamiento y prueba es bastante similar, lo que significa que nuestro modelo no está sobreajustado.

Selección de funciones de paso hacia atrás

La selección de funciones de paso hacia atrás, como sugiere el nombre, es exactamente lo contrario de la selección de funciones de paso hacia adelante que estudiamos en la última sección. En el primer paso de la selección de características del paso hacia atrás, se elimina una característica del conjunto de características por turnos y se evalúa el rendimiento del clasificador.

Se conserva el conjunto de funciones que produce el mejor rendimiento. En el segundo paso, de nuevo se elimina una característica de forma rotatoria y se evalúa el rendimiento de todas las combinaciones de características excepto las 2 características. Este proceso continúa hasta que la cantidad especificada de características permanezca en el conjunto de datos.

Paso hacia atrás en la selección de características en Python

En esta sección, implementaremos la selección de funciones de paso hacia atrás en el Gestión de siniestros de BNP Paribas Cardif. El paso de preprocesamiento seguirá siendo el mismo que en la sección anterior. El único cambio será en el forward parámetro de la SequentiaFeatureSelector clase. En el caso de la selección de la función de retroceso, configuraremos este parámetro en False. Ejecute el siguiente script:

from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.metrics import roc_auc_score
from mlxtend.feature_selection import SequentialFeatureSelector

feature_selector = SequentialFeatureSelector(RandomForestClassifier(n_jobs=-1),
           k_features=15,
           forward=False,
           verbose=2,
           scoring='roc_auc',
           cv=4)

features = feature_selector.fit(np.array(train_features.fillna(0)), train_labels)

Para ver la función seleccionada como resultado de la eliminación del paso hacia atrás, ejecute el siguiente script:

filtered_features= train_features.columns[list(features.k_feature_idx_)]
filtered_features

La salida se ve así:

Index(['v7', 'v8', 'v10', 'v17', 'v34', 'v38', 'v45', 'v50', 'v51', 'v61',
       'v94', 'v99', 'v119', 'v120', 'v129'],
      dtype="object")

Finalmente, evaluemos el rendimiento de nuestro clasificador de bosque aleatorio en las características seleccionadas como resultado de la selección de características retrocediendo. Ejecute el siguiente script:

clf = RandomForestClassifier(n_estimators=100, random_state=41, max_depth=3)
clf.fit(train_features[filtered_features].fillna(0), train_labels)

train_pred = clf.predict_proba(train_features[filtered_features].fillna(0))
print('Accuracy on training set: {}'.format(roc_auc_score(train_labels, train_pred[:,1])))

test_pred = clf.predict_proba(test_features[filtered_features].fillna(0))
print('Accuracy on test set: {}'.format(roc_auc_score(test_labels, test_pred [:,1])))

La salida se ve así:

Accuracy on training set: 0.7095207938140247
Accuracy on test set: 0.7114624676445211

Puede ver que el rendimiento logrado en el conjunto de entrenamiento es similar al logrado mediante la selección de funciones de avance. Sin embargo, en el conjunto de prueba, la selección de funciones hacia atrás funcionó ligeramente mejor.

Selección exhaustiva de funciones

En una selección exhaustiva de características, el rendimiento de un algoritmo de Machine Learning se evalúa frente a todas las combinaciones posibles de las características del conjunto de datos. Se selecciona el subconjunto de funciones que ofrece el mejor rendimiento. El algoritmo de búsqueda exhaustiva es el algoritmo más codicioso de todos los métodos de envoltura, ya que prueba todas las combinaciones de funciones y selecciona la mejor.

Una desventaja de la selección exhaustiva de funciones es que puede ser más lenta en comparación con el método de paso hacia adelante y hacia atrás, ya que evalúa todas las combinaciones de funciones.

Selección exhaustiva de funciones en Python

En esta sección, implementaremos la selección de funciones de paso hacia atrás en el Gestión de siniestros de BNP Paribas Cardif. El paso de preprocesamiento seguirá siendo similar al de la selección de la función Paso adelante.

Para implementar una selección de características exhaustiva, usaremos ExhaustiveFeatureSelector función de la mlxtend.feature_selection biblioteca. La clase tiene min_featuresy max_features atributos que se pueden utilizar para especificar el número mínimo y máximo de características en la combinación.

Ejecute el siguiente script:

from mlxtend.feature_selection import ExhaustiveFeatureSelector
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.metrics import roc_auc_score

feature_selector = ExhaustiveFeatureSelector(RandomForestClassifier(n_jobs=-1),
           min_features=2,
           max_features=4,
           scoring='roc_auc',
           print_progress=True,
           cv=2)

Creamos nuestro selector de funciones, ahora necesitamos llamar al fit en nuestro selector de funciones y pásale los conjuntos de entrenamiento y prueba como se muestra a continuación:

features = feature_selector.fit(np.array(train_features.fillna(0)), train_labels)

Tenga en cuenta que la secuencia de comandos anterior puede tardar bastante en ejecutarse. Para ver la función seleccionada como resultado de la eliminación del paso hacia atrás, ejecute el siguiente script:

filtered_features= train_features.columns[list(features.k_feature_idx_)]
filtered_features

Finalmente, para ver el rendimiento del clasificador de bosque aleatorio en las características seleccionadas como resultado de una selección exhaustiva de características. Ejecute el siguiente script:

clf = RandomForestClassifier(n_estimators=100, random_state=41, max_depth=3)
clf.fit(train_features[filtered_features].fillna(0), train_labels)

train_pred = clf.predict_proba(train_features[filtered_features].fillna(0))
print('Accuracy on training set: {}'.format(roc_auc_score(train_labels, train_pred[:,1])))

test_pred = clf.predict_proba(test_features[filtered_features].fillna(0))
print('Accuracy on test set: {}'.format(roc_auc_score(test_labels, test_pred [:,1])))

Conclusión

Los métodos de envoltura son algunos de los algoritmos más importantes que se utilizan para la selección de funciones para un algoritmo de Machine Learning específico. En este artículo, estudiamos diferentes tipos de métodos de envoltura junto con su implementación práctica. Estudiamos el paso adelante, el paso atrás y métodos exhaustivos para la selección de funciones.

Como regla general, si el conjunto de datos es pequeño, el método de selección de características exhaustivo debe ser la elección; sin embargo, en el caso de conjuntos de datos grandes, se deben preferir los métodos de selección de características de paso hacia adelante o hacia atrás.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad