Cross-validation
One train and validation split can make a model look unusually good or unusually weak. Cross-validation repeats the comparison on several held-out partitions of the training data. Each row gets a turn outside the fit. Keep preprocessing inside the pipeline so each scaler learns only its fold. You will collect fold scores, summarize their spread and create out-of-fold probabilities. The final test set stays separate because choosing a model from repeated scores is already a form of selection. A rare event also needs enough positive examples in every fold; a score isn't useful when its required class is absent.
fold_scores = cross_val_score(base, X_train, y_train, cv=cv, scoring='roc_auc')
Cross-validation refits the whole pipeline inside each training fold.