- Вопрос или проблема
- Ответ или решение
- 1. Проблемы с настройками модели
- 1.1 Неподходящие гиперпараметры
- 1.2 Избыточное снижение размера выборки
- 2. Проблемы с данными
- 2.1 Неправильная обработка несбалансированности классов
- 2.2 Проблемы с признаками
- 3. Оценка и выбор метрик
- 3.1 Неправильная интерпретация метрик
- 3.2 Ненадежные предсказания
- В заключение
Вопрос или проблема
Я нов в этой области и работаю над простой задачей обнаружения мошенничества с следующим распределением классов:
Метка 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 могут быть индикатором проблем с настройками модели, предобработкой данных или неэффективной оценкой метрик. Проводите эксперименты с гиперпараметрами и обратите внимание на стратегии работы с несбалансированными данными. Также, тестируйте модель с использованием различных метрик, чтобы получать более полное представление о модели и её производительности. Следуя приведенным рекомендациям, вы сможете улучшить качество модели и достичь лучших результатов в задаче обнаружения мошенничества.