Интеграция RFE с GBM для выбора функций и настройки гиперпараметров

Меня зовут Лукас, и я относительно новичок в области машинного обучения. Я написал этот код с помощью онлайн-документации и руководств. Однако мне нужна помощь в понимании правильности интеграции RFE() с GBM().

def evaluateAlgorithm(X_train, X_test, y_train, y_test, dataset):
    Kfold = StratifiedKFold(n_splits=20, shuffle=True)

    GBM = GradientBoostingClassifier(
        loss='log_loss', learning_rate=0.01,
        n_estimators=1000, subsample=0.9,
        min_samples_split=2, min_samples_leaf=1,
        min_weight_fraction_leaf=0.0, max_depth=8,
        init=None, random_state=None,
        max_features=None, verbose=0,
        max_leaf_nodes=None, warm_start=False)

    pipeline = Pipeline(steps=[['feature_selection', RFE(GBM)], ['model', GBM]])

    parameters = {'model__learning_rate': [0.01, 0.02, 0.03],
                  'model__subsample': [0.9, 0.5, 0.3, 0.1],
                  'model__n_estimators': [100, 500, 1000],
                  'model__max_depth': [1, 2, 3],
                  'feature_selection__n_features_to_select': [7, 14, 27]}

    grid_GBM = GridSearchCV(estimator=pipeline, param_grid=parameters, cv=Kfold,
                            verbose=1, n_jobs=-1, refit=True, scoring='accuracy')
    grid_GBM.fit(X_train, y_train)

    print("\n======================================================================== = ")
    print(" Results from Grid Search Gradient Boosting")
    print("======================================================================== = ")
    print("\n The best estimator across ALL searched params: \n", grid_GBM.best_estimator_)
    print("\n The best score across ALL searched params: \n", grid_GBM.best_score_)
    print("\n The best parameters across ALL searched params: \n", grid_GBM.best_params_)
    print("\n======================================================================== = ")

    # Obtain features selected by RFE
    rfe_selected_features_indices = grid_GBM.best_estimator_['feature_selection'].support_
    rfe_selected_features_names = X_train.columns[rfe_selected_features_indices]
    print("Features selected by RFE:", rfe_selected_features_names)

    model_GBM = grid_GBM.best_estimator_

    # Cross-validation
    cv_results_GBM = cross_val_score(model_GBM, X_train, y_train, cv=Kfold, scoring='accuracy', n_jobs=-1, verbose=0)

    print()
    print("Cross Validation results Gradient Boosting: ", cv_results_GBM)
    prt_string = "CV Mean accuracy: %f (Std: %f)" % (cv_results_GBM.mean(), cv_results_GBM.std())
    print(prt_string)

    trained_Model_GBM = model_GBM.fit(X_train, y_train)

    print();
    print('========================================================')
    print();
    print(trained_Model_GBM.get_params(deep=True))
    print();
    print('=========================================================')

    # Make predictions on the test set
    pred_Labels_GBM = trained_Model_GBM.predict(X_test)
    pred_proba_GBM = trained_Model_GBM.predict_proba(X_test)

    # Evaluate performance
    print();
    print('Evaluation of the trained model Gradient Boosting: ')
    accuracy = accuracy_score(y_test, pred_Labels_GBM)
    print();
    print('Accuracy Gradient Boosting: ', accuracy)
    precision = precision_score(y_test, pred_Labels_GBM, pos_label='positive')
    print();
    print('Precision Gradient Boosting: ', precision)
    recall = recall_score(y_test, pred_Labels_GBM, pos_label='positive')
    print();
    print('Recall Score Gradient Boosting: ', recall)
    f1 = f1_score(y_test, pred_Labels_GBM, pos_label='positive')
    print();
    print('f1 Score Gradient Boosting: ', f1)
    confusion_mat = confusion_matrix(y_test, pred_Labels_GBM)
    classReport = classification_report(y_test, pred_Labels_GBM)
    print();
    print('Classification Report Gradient Boosting: \n', classReport)
    kappa_score = cohen_kappa_score(y_test, pred_Labels_GBM)
    print();
    print('Kappa Score Gradient Boosting: ', kappa_score)

    skplt.estimators.plot_learning_curve(model_GBM, X_train, y_train, figsize=(8, 6))
    plt.show()

    skplt.metrics.plot_roc(y_test, pred_proba_GBM, figsize=(8, 6));
    plt.show()

    skplt.metrics.plot_confusion_matrix(y_test, pred_Labels_GBM, figsize=(8, 6));
    plt.show()

    skplt.metrics.plot_precision_recall(y_test, pred_proba_GBM,
                                        title='Precision-Recall Curve', plot_micro=True,
                                        classes_to_plot=None, ax=None, figsize=(8, 6),
                                        cmap='nipy_spectral', title_fontsize='large',
                                        text_fontsize='medium');
    plt.show()


evaluateAlgorithm(X_train, X_test, y_train, y_test, dataset)

Моя цель — использовать RFE для поиска наилучшего сочетания функций наряду с поиском по сетке GBM для лучших гиперпараметров. Однако похоже, что RFE находит только лучшие функции перед гиперпараметрами поиска по сетке. Как я могу решить эту проблему, чтобы оба процесса происходили одновременно? Идея состоит в том, чтобы добиться наилучшего сочетания обоих критериев. Кроме того, есть ли у вас какие-либо предложения по улучшению этого кода?

Основываясь на ответе Бена Рейнигера, я пришел к следующему результату.

    pipeline = Pipeline(steps=[['RFE', RFE(estimator=GBM)]])

parameters = {
    'RFE__estimator__learning_rate': [0.001, 0.01, 0.05],#0.01, 0.02, 0.03, 0.05
    'RFE__estimator__subsample': [0.9, 0.5, 0.1], #0.7,  0.3,
    'RFE__estimator__n_estimators': [500, 1000, 2000], #1500
    'RFE__estimator__max_depth': [4, 5, 6,], #3, 7, 8
    #'RFE__estimator__max_features': ['auto', 'sqrt', 'log2', None],
    #'RFE__estimator__min_samples_split': [2, 5, 10],
    #'RFE__estimator__min_samples_leaf': [1, 2, 4],
    #'RFE__estimator__max_leaf_nodes': [None, 5, 10, 20],
    'RFE__n_features_to_select': [5, 10, 20]
}
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как написано, ваш код настраивает гиперпараметры окончательной модели, но не гиперпараметры GBM на этапе выбора функций. Несколько вариантов:

  1. Расширьте пространство поиска, включив в него гиперпараметры select-gbm, например. feature_selection__estimator__max_depth.

  2. Отбросьте шаг модели. RFE предоставляет доступ к окончательной модели выбранного набора функций (estimator_), а методы, которые вам могут понадобиться от нее, становятся доступными непосредственно из объекта RFE (например, rfe.predict). Итак, просто измените имена гиперпараметров, как указано выше.

Разница между этими подходами заключается в том, что первый позволяет выбрать ГБМ с гиперпараметрами, отличными от модели-ГБМ. Это будет более затратно в вычислительном отношении, но более гибко. Лично я был бы удивлён, если бы это дало значительные улучшения, поэтому я бы предложил второй подход, если у вас нет времени и желания экспериментировать.

Основываясь на ответе Бена Рейнигера, я добавил новое поле в вопрос с решением.

Lucas F. T. Leonardo 24.05.2024 07:58

Другие вопросы по теме