Every example so far used a synthetic dataset built for this course. Fraud detection is worth a closer look at a real, publicly available dataset: the Credit Card Fraud dataset released by the Machine Learning Group at Universite Libre de Bruxelles, built from real European cardholders' transactions over two days in September 2013, with the original transaction details anonymised through a PCA transformation for privacy, leaving 28 numeric features plus the raw transaction amount.
Case study: A Dataset That Is 0.17 Percent Fraud
The ULB dataset contains 284,807 transactions. Only 492 of them, 0.17 percent, are fraudulent. This is not an unusually extreme example chosen to make a point; it is simply what real-world fraud looks like, and it is the single most cited real-world illustration of the class-imbalance problem this unit has raised repeatedly and Unit 6 builds its entire evaluation framework around. A classifier that predicts "legitimate" for every transaction in this dataset is correct 99.83 percent of the time and catches not a single fraud.
- Scale the transaction amount feature; the anonymised PCA features already arrive roughly standardised, but amount does not.
- Split before any resampling, so the test set reflects the real, severe imbalance the model will face in production.
- Train on a class-weighted or resampled training set (
class_weight="balanced"is the simplest starting point). - Evaluate with precision, recall, and the precision-recall curve from Unit 6, never with accuracy alone.
- Set the decision threshold deliberately, based on the real cost of a missed fraud versus the cost of a false alarm that blocks a legitimate purchase, not the default 0.5.
fraud_random_forest.py
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
# df: the ULB dataset, with columns V1..V28 (already PCA-anonymised),
# Amount, and Class (1 = fraud)
df["scaled_amount"] = StandardScaler().fit_transform(df[["Amount"]])
X = df.drop(columns=["Amount", "Class"])
y = df["Class"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
fraud_model = RandomForestClassifier(
n_estimators=300, max_depth=8, class_weight="balanced", random_state=42
)
fraud_model.fit(X_train, y_train)
Key takeaway
Decision trees split on the single best question at each step and are easy to read but easy to overfit. Random forests average many trees to cancel out that overfitting. Support vector machines find the widest-margin boundary, using the kernel trick to draw curved boundaries. Gradient boosting trains trees sequentially so each one corrects the last, usually winning on tabular security data at the cost of more careful tuning.

