Spaces:
Sleeping
Sleeping
File size: 6,081 Bytes
bd41331 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | # src/models/train_model.py
"""
Main training script for fraud detection model
"""
import pandas as pd
import numpy as np
import logging
import warnings
from sklearn.impute import SimpleImputer
from imblearn.over_sampling import SMOTE
from imblearn.pipeline import Pipeline as ImbPipeline
import xgboost as xgb
from catboost import CatBoostClassifier
import lightgbm as lgb
from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression
from src.config.parameters import (
DATA_PARAMS, MODEL_PARAMS, SMOTE_PARAMS,
ARTIFACT_PATHS, RAW_DATA_DIR
)
from src.utils.data_preprocessing import DataPreprocessor
from src.utils.feature_engineering import FeatureEngineer
from src.utils.model_utils import ModelTrainer, save_model_artifacts
from src.utils.monitoring import setup_logging, log_model_performance
warnings.filterwarnings('ignore')
def main():
"""Main training pipeline"""
# Setup logging
logger = setup_logging()
logger.info("="*50)
logger.info("FRAUD DETECTION MODEL TRAINING STARTED")
logger.info("="*50)
try:
# 1. Data Loading and Preprocessing
logger.info("Step 1: Data Loading and Preprocessing")
preprocessor = DataPreprocessor()
# Load data
df = preprocessor.load_data(DATA_PARAMS['raw_data_path'])
# Basic preprocessing
df = preprocessor.basic_preprocessing(df)
# 2. Feature Engineering
logger.info("Step 2: Feature Engineering")
feature_engineer = FeatureEngineer()
df_processed = feature_engineer.engineer_features(df, is_training=True)
# Update preprocessor with feature engineering artifacts
preprocessor.scaler = feature_engineer.scaler
preprocessor.legit_amount_mean = feature_engineer.legit_amount_mean
preprocessor.amount_bin_edges = feature_engineer.amount_bin_edges
preprocessor.top_corr_features = feature_engineer.top_corr_features
# Also save the time scaler
if hasattr(feature_engineer, 'time_scaler'):
preprocessor.time_scaler = feature_engineer.time_scaler
# 3. Train-Test Split
logger.info("Step 3: Train-Test Split")
X_train, X_test, y_train, y_test = preprocessor.split_data(df_processed)
# Save preprocessing artifacts
preprocessor.save_preprocessing_artifacts(df_processed, X_train)
# 4. Model Training Setup
logger.info("Step 4: Model Training Setup")
trainer = ModelTrainer()
# Define base models for stacking
base_models = [
('xgb', xgb.XGBClassifier(**MODEL_PARAMS['xgb'])),
('cat', CatBoostClassifier(**MODEL_PARAMS['catboost'])),
('lgb', lgb.LGBMClassifier(**MODEL_PARAMS['lightgbm']))
]
meta_model = LogisticRegression(**MODEL_PARAMS['logistic_regression'])
stacking_classifier = StackingClassifier(
estimators=base_models,
final_estimator=meta_model,
cv=5
)
# Create pipeline with SMOTE
pipeline = ImbPipeline([
('imputer', SimpleImputer(strategy='median')),
('smote', SMOTE(**SMOTE_PARAMS)),
('classifier', stacking_classifier)
])
# 5. Model Training and Evaluation
logger.info("Step 5: Model Training and Evaluation")
# Train and evaluate with MLflow logging
results = trainer.train_and_log_model(
model=pipeline,
X_train=X_train,
y_train=y_train,
X_test=X_test,
y_test=y_test,
model_name="Stacking_Ensemble_SMOTE",
parameters={
**MODEL_PARAMS,
**SMOTE_PARAMS,
'pipeline_steps': ['imputer', 'smote', 'stacking_classifier']
}
)
# 6. Save Model Artifacts
logger.info("Step 6: Saving Model Artifacts")
save_model_artifacts(
model=results['model'],
optimal_threshold=results['optimal_threshold']
)
# 7. Log Final Results
logger.info("Step 7: Final Results Summary")
log_model_performance(
metrics={k: v for k, v in results['test_metrics'].items()
if isinstance(v, (int, float))},
model_name="Final Stacking Ensemble"
)
logger.info("="*50)
logger.info("TRAINING COMPLETED SUCCESSFULLY!")
logger.info("="*50)
# Print summary
print("\n" + "="*60)
print("FRAUD DETECTION MODEL TRAINING SUMMARY")
print("="*60)
print(f"Dataset Shape: {df.shape}")
print(f"Features after Engineering: {X_train.shape[1]}")
print(f"Training Samples: {X_train.shape[0]}")
print(f"Test Samples: {X_test.shape[0]}")
print(f"Fraud Cases (Train): {y_train.sum()}")
print(f"Fraud Cases (Test): {y_test.sum()}")
print("\nKey Metrics (Test Set):")
print(f" Accuracy: {results['test_metrics']['accuracy']:.4f}")
print(f" Precision: {results['test_metrics']['precision']:.4f}")
print(f" Recall: {results['test_metrics']['recall']:.4f}")
print(f" F1-Score: {results['test_metrics']['f1']:.4f}")
print(f" ROC-AUC: {results['test_metrics']['roc_auc']:.4f}")
print(f" PR-AUC: {results['test_metrics']['pr_auc']:.4f}")
print(f"Optimal Threshold: {results['optimal_threshold']:.4f}")
print(f"\nModel saved to: {ARTIFACT_PATHS['model_pipeline']}")
print("="*60)
return results
except Exception as e:
logger.error(f"Training failed with error: {str(e)}", exc_info=True)
raise
if __name__ == "__main__":
results = main() |