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

    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.

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *