Метрики LGBM равны 0.0

Вопрос или проблема

Я нов в этой области и работаю над простой задачей обнаружения мошенничества с следующим распределением классов:

Метка 0: 142,900 образцов

Метка 1: 16,530 образцов

Я обучаю модель LightGBM, используя Optuna для подбора гиперпараметров. Я запустил первый эксперимент, но оценка (предположительно точность или аналогичный показатель) равна 0.0. Этап предобработки был выполнен правильно, и данные выглядят нормально.

Я не уверен, почему это происходит. Кто-нибудь сталкивался с подобной проблемой? Есть какие-либо советы о том, что может быть причиной этого или как это устранить?

Заранее спасибо за вашу помощь!

def objective(trial, X, y):
    params = {
        'objective': 'binary',
        'metric': 'binary_logloss',
        'boosting_type': 'gbdt',
        'verbosity': -1,
        'max_depth': -1,
        'learning_rate': trial.suggest_float('learning_rate', 0.005, 0.01, log=True),
        'num_leaves': trial.suggest_int('num_leaves', 400, 500),
        'feature_fraction': trial.suggest_float('feature_fraction', 0.3, 0.6),
        'bagging_fraction': trial.suggest_float('bagging_fraction', 0.4, 0.7),
        'min_child_weight': trial.suggest_float('min_child_weight', 0.01, 0.1, log=True),
        'min_data_in_leaf': trial.suggest_int('min_data_in_leaf', 50, 150),
        'reg_alpha': trial.suggest_float('reg_alpha', 0.1, 1.0, log=True),
        'reg_lambda': trial.suggest_float('reg_lambda', 0.1, 1.0, log=True),
        'random_state': RANDOM_STATE
    }

    NFOLDS = 5
    folds = StratifiedKFold(n_splits=NFOLDS, shuffle=True, random_state=RANDOM_STATE)
    columns = X.columns
    splits = folds.split(X, y)
    y_oof = np.zeros(X.shape[0])
    score = 0

    for fold_n, (train_index, valid_index) in enumerate(splits):
        logging.info(f"Обработка сложения {fold_n + 1} из {NFOLDS}.")
        X_train, X_valid = X[columns].iloc[train_index], X[columns].iloc[valid_index]
        y_train, y_valid = y.iloc[train_index], y.iloc[valid_index]

        train_data = lgb.Dataset(X_train, label=y_train)
        valid_data = lgb.Dataset(X_valid, label=y_valid)

        model = lgb.train(params, train_data, num_boost_round=1000, valid_sets=[valid_data], 
                          callbacks=[early_stopping(stopping_rounds=50)])

        y_pred_valid = model.predict(X_valid)
        y_oof[valid_index] = y_pred_valid
        fold_f1 = f1_score(y_valid, [1 if pred > 0.2 else 0 for pred in y_pred_valid])
        logging.info(f"Сложение {fold_n + 1} | F1 Оценка: {fold_f1}")
        score += fold_f1 / NFOLDS

    logging.info(f"Средняя F1 Оценка = {score}")
    logging.info(f"F1 Оценка вне сложений = {f1_score(y, [1 if pred > 0.2 else 0 for pred in y_oof])}")

    return score

if __name__ == "__main__":
    train_df = pd.read_csv(DATA_PATH, encoding='utf-8')
    X = train_df.drop(columns=['isFraud'])
    y = train_df['isFraud']

    X = preprocess_data(X, MODE, DIR)
    X_clnd, dropped_features = drop_corr_features(X, threshold=0.95)

    X_scaled = scale_features(X_clnd)
    X_scaled_df = pd.DataFrame(X_scaled, columns=X_clnd.columns)

    X_train, X_test, y_train, y_test = train_test_split(X_scaled_df, y, test_size=TEST_SIZE, random_state=RANDOM_STATE, stratify=y)

    study = optuna.create_study(direction='maximize', study_name="maximize_auc")
    study.optimize(lambda trial: objective(trial, X_train, y_train), n_trials=N_TRIALS)

    best_params = study.best_params
    logging.info(f"Лучшие гиперпараметры: {best_params}")

    final_model = lgb.LGBMClassifier(**best_params)
    final_model.fit(X_train, y_train)

    y_test_pred = final_model.predict(X_test)
    f1 = f1_score(y_test, y_test_pred)
    precision = precision_score(y_test, y_test_pred)
    recall = recall_score(y_test, y_test_pred)
    roc_auc = roc_auc_score(y_test, final_model.predict_proba(X_test)[:, 1])

    cm = confusion_matrix(y_test, y_test_pred)
    logging.info(f"Матрица замешивания:\n{cm}")

    logging.info(f"F1 Оценка: {f1}")
    logging.info(f"Точность: {precision}")
    logging.info(f"Полнота: {recall}")
    logging.info(f"ROC AUC Оценка: {roc_auc}")

2024-11-16 19:27:35,892 - INFO - Матрица замешивания:
[[28580 0]
[ 3306 0]]
2024-11-16 19:27:35,892 - INFO - F1 Оценка: 0.0
2024-11-16 19:27:35,907 - INFO - Точность: 0.0
2024-11-16 19:27:35,907 - INFO - Полнота: 0.0
2024-11-16 19:27:35,907 - INFO - ROC AUC Оценка: 0.49814946698688517

Ответ или решение

Ваша ситуация с получением метрик модели LightGBM равными 0.0, несмотря на корректно выполненный этап предобработки данных, может возникнуть по нескольким причинам. Поскольку вы работаете с задачей обнаружения мошенничества в условиях значительного несоответствия классов (по отношению 1:8.63 между метками 0 и 1), это может существенно повлиять на производительность модели. Рассмотрим детально некоторые возможные причины и пути их устранения.

1. Проблемы с настройками модели

1.1 Неподходящие гиперпараметры

Как вы упомянули, вы используете Optuna для настройки гиперпараметров. Однако, слабые настройки могут не позволить модели адекватно учиться. Например, значение num_leaves в диапазоне от 400 до 500 является довольно большим в контексте ваших данных. Попробуйте снизить это значение до 31-127, чтобы избежать переобучения.

1.2 Избыточное снижение размера выборки

Ваши параметры bagging_fraction и feature_fraction, если они слишком низкие, могут привести к тому, что модель недостаточно обучается. Убедитесь, что эти значения находятся в оптимальных пределах (обычно от 0.6 до 1.0 для feature_fraction).

2. Проблемы с данными

2.1 Неправильная обработка несбалансированности классов

Поскольку у вас явный дисбаланс классов, модель может игнорировать класс 1, так как больший класс в 0. Попробуйте использовать методы, такие как:

  • Увеличение (oversampling) класса 1
  • Уменьшение (undersampling) класса 0
  • Введение взвешивания классов (class_weight), где вес класса 1 будет значительно выше.

2.2 Проблемы с признаками

Проверьте, не теряются ли информативные признаки на этапе очистки данных и отбора. Используйте методики, такие как корреляционный анализ или одновременное использование модели SHAP для оценки важности признаков.

3. Оценка и выбор метрик

3.1 Неправильная интерпретация метрик

Вы используете F1 Score как основную метрику. Обратите внимание, что на высоком несоответствии классов этого может быть недостаточно. Рассмотрите возможность использования ROC AUC, чтобы получить более дифференцированное представление о работоспособности модели.

3.2 Ненадежные предсказания

Из-за недообученности модели или её игнорирования класса 1, предсказания складываются в 0. Это видно из Вашего confusion matrix, где все предсказания относятся к классу 0. Убедитесь, что в ваших обучающих данных присутствует достаточное количество образцов класса 1.

В заключение

Ваши метрики равные 0.0 могут быть индикатором проблем с настройками модели, предобработкой данных или неэффективной оценкой метрик. Проводите эксперименты с гиперпараметрами и обратите внимание на стратегии работы с несбалансированными данными. Также, тестируйте модель с использованием различных метрик, чтобы получать более полное представление о модели и её производительности. Следуя приведенным рекомендациям, вы сможете улучшить качество модели и достичь лучших результатов в задаче обнаружения мошенничества.

Оцените материал
Добавить комментарий

Капча загружается...