Project 10 β Autoencoder Anomaly Detection
Level: Advanced | Dataset: Credit Card Fraud (Kaggle) | Framework: PyTorch
Objective
Build an Autoencoder that learns the distribution of normal transactions and flags anomalies via high reconstruction error. Cover: encoder-decoder architecture, bottleneck, reconstruction loss, threshold tuning, unsupervised anomaly detection.
Project Structure
10_autoencoder_anomaly/
βββ notebooks/
β βββ 01_eda.ipynb
β βββ 02_preprocessing.ipynb
β βββ 03_train_evaluate.ipynb
βββ data/raw/creditcard.csv
βββ data/processed/
βββ models/model.pkl
βββ charts/
βββ path_utils.py
βββ dashboard_core.py
βββ app.py
Dataset: mlg-ulb/credit-card-fraud-detection β Kaggle.
284,807 transactions, 492 fraud (0.17% fraud rate).
Features: V1-V28 (PCA-transformed), Amount, Time. Target: Class (0=normal, 1=fraud).
Notebook 01 β EDA (01_eda.ipynb)
STOP 1 β Load & Class Distribution
- Load creditcard.csv
- Print class distribution: 284,315 normal, 492 fraud
- This is extreme imbalance: 99.83% vs 0.17%
- Agent stops here. Explain:
- Why this is a perfect Autoencoder use case: we have very few fraud examples
- The unsupervised insight: train ONLY on normal β AE learns to reconstruct normal well β fraud reconstructed poorly
- Why supervised models struggle here: too few fraud examples even with class weights
- Real-world context: in production, fraud patterns change constantly β unsupervised is more robust
- Wait for user confirmation before continuing
STOP 2 β Feature Analysis
- Plot distribution of
Amountβ heavily skewed, log transform - Plot distribution of V1, V5, V14 (most fraud-discriminative PCA components)
- Overlay normal vs fraud distributions for V14
- Agent stops here. Explain:
- What V1-V28 are: principal components of original transaction features (anonymized by Kaggle)
- Why Amount needs special treatment (raw dollar amount vs scaled PCA features)
- What overlapping distributions mean: fraud and normal transactions look similar to linear models
- How the AE exploits the subtle difference: it learns the joint distribution of all features
- Wait for confirmation
STOP 3 β Reconstruction Concept Walkthrough
- Explain (with markdown cells) what reconstruction means:
- AE takes input x β compresses to z (bottleneck) β reconstructs xΜ
- Loss: MSE(x, xΜ) averaged over all features
- At inference: high MSE = anomalous
- Agent stops here. Explain:
- The information bottleneck principle: compression forces the model to learn the "essence"
- Why bottleneck width matters: too wide = AE memorizes everything (no anomaly detection), too narrow = loses normal patterns too
- What reconstruction error distribution looks like for normal vs fraud
- Wait for confirmation
Notebook 02 β Preprocessing (02_preprocessing.ipynb)
STOP 4 β Isolation of Normal Class
- Separate:
normal_df = df[df['Class'] == 0] - Training set: 80% of normal only (no fraud in training)
- Validation set: 10% normal + ALL 492 fraud (to tune threshold)
- Test set: remaining 10% normal + reserved 100 fraud
- Agent stops here. Explain:
- Why we train ONLY on normal data β this is the core principle of AE-based anomaly detection
- Why we include fraud in validation: to find the optimal reconstruction error threshold
- The correct split strategy for unsupervised anomaly detection
- Wait for confirmation
STOP 5 β Feature Scaling
- Log transform
Amount:np.log1p(df['Amount']) - Drop
Timecolumn (not informative after PCA) StandardScalerfit on normal train features only- Apply to normal train, val (normal+fraud), test (normal+fraud)
- Agent stops here. Explain:
- Why log1p for Amount: log(1+x) handles zero correctly, compresses large values
- Why StandardScaler fit only on normal train: we're assuming normal distribution of normal transactions
- What happens if we scale fraud using fraud statistics (leakage, defeats the purpose)
- Wait for confirmation
STOP 6 β Tensor Dataset
- Normal train: X only (no labels needed for training β unsupervised)
- Val/Test: (X, y) pairs where y is the fraud label for evaluation
- DataLoader for train: batch_size=256, shuffle=True
- Agent stops here. Explain:
- Why training DataLoader has no labels: AE is trained to minimize reconstruction error, not classify
- How this is fundamentally different from all previous supervised projects
- What "unsupervised learning" means in practice
- Wait for confirmation
Notebook 03 β Train & Evaluate (03_train_evaluate.ipynb)
STOP 7 β Autoencoder Architecture
Encoder:
Linear(29, 64) β ReLU β Dropout(0.1)
Linear(64, 32) β ReLU
Linear(32, 16) β ReLU [bottleneck = 16]
Decoder:
Linear(16, 32) β ReLU
Linear(32, 64) β ReLU
Linear(64, 29) [no activation β reconstruct any value]
Forward: x β z = encode(x) β x_hat = decode(z) β return x_hat
- Agent stops here. Explain:
- Symmetric encoder-decoder: decoder mirrors encoder structure
- Bottleneck dimension=16: compresses 29 features to 16 (forced information bottleneck)
- Why no activation at decoder output: output must match input range (any real value after scaling)
- What the latent space z represents: compressed representation of the transaction
- How to choose bottleneck size: experiment β too small loses normal patterns, too large = no compression
- Wait for confirmation
STOP 8 β Reconstruction Loss
- Use
nn.MSELoss(reduction='none')β keep per-sample, per-feature losses - Average over features for per-sample reconstruction error
- Training loss: mean of per-sample errors
- Agent stops here. Explain:
- Why
reduction='none': we need per-sample error at inference time - What reconstruction error for ONE sample looks like: scalar value (mean over 29 features)
- Why MSE penalizes large reconstruction errors quadratically β good for detecting anomalies
- Alternative: MAE loss β less sensitive to outliers (sometimes better for AE)
- Why
- Wait for confirmation
STOP 9 β Training Loop
- Train on NORMAL ONLY for 50 epochs
- Track train reconstruction error per epoch
- Also compute val reconstruction error for normal vs fraud separately
- Plot: normal reconstruction error distribution vs fraud reconstruction error distribution
- Agent stops here. Explain:
- What we expect to see: two distributions, fraud shifted right (higher error)
- Why the distributions might overlap: some fraud looks like normal, some normal looks weird
- The separation quality directly predicts AUC
- What "collapse" looks like if bottleneck is too wide: both distributions identical
- Wait for confirmation
STOP 10 β Threshold Tuning
- Compute reconstruction error for ALL validation samples (normal + fraud)
- Try thresholds from min to max error at 100 steps
- For each threshold: compute Precision, Recall, F1
- Plot F1 vs threshold curve
- Select threshold that maximizes F1 (or recall, depending on business requirement)
- Agent stops here. Explain:
- What threshold selection is: converting a continuous score to binary prediction
- The precision-recall tradeoff at different thresholds
- In fraud detection, what is worse: false positive (block good transaction) vs false negative (miss fraud)?
- Why we tune on val, evaluate on test (never touch test during tuning)
- Wait for confirmation
STOP 11 β Evaluation on Test Set
- Apply tuned threshold to test set
- Compute: Precision, Recall, F1, AUC-ROC, AUC-PR
- Plot ROC curve and Precision-Recall curve
- Agent stops here. Explain:
- Why AUC-PR is more informative than AUC-ROC for extreme imbalance
- What AUC-PR = 0.5 means on a 0.17% fraud rate (baseline = 0.0017!)
- Why ROC can be misleadingly optimistic with extreme imbalance
- The business metric: catch rate (recall on fraud) at a given false positive rate
- Wait for confirmation
STOP 12 β Latent Space Visualization
- Encode all test samples (normal + fraud) to get z vectors [N, 16]
- Apply t-SNE or PCA to reduce to 2D
- Plot with color: blue=normal, red=fraud
- Agent stops here. Explain:
- What we hope to see: fraud forming clusters away from normal
- What t-SNE shows that PCA doesn't: non-linear clustering structure
- Why fraud might not perfectly separate in latent space (some fraud IS similar to normal transactions)
- How this visualization helps in understanding model failure modes
- Wait for confirmation
STOP 13 β Save & Inference
- Save model.state_dict(), scaler, threshold
- Write
predict_fraud(transaction_dict)β label, reconstruction_error, is_fraud - Agent stops here. Explain:
- Complete inference pipeline: dict β preprocess (log Amount, scale) β tensor β model.eval() β reconstruct β MSE β compare to threshold β return
- Why we save the threshold with the model (it's part of the "model")
- How to update threshold in production as fraud patterns evolve
- Wait for confirmation
dashboard_core.py
Functions:
load_model_scaler_threshold()β model, scaler, thresholdpredict_fraud(transaction_dict)β reconstruction_error, is_fraud, boolget_error_distributions()β (normal_errors, fraud_errors) arraysget_roc_pr_curves()β dict of curve dataget_latent_viz()β 2D coords + labels
app.py β Streamlit (~80 lines)
Sections:
- Sidebar: sliders for V1, V14, V17, Amount (most discriminative features)
- Main: "Analyze Transaction" β show reconstruction error + fraud/normal verdict
- Tab 1: Training reconstruction error curve
- Tab 2: Error distribution histogram (normal vs fraud overlap)
- Tab 3: ROC + PR curves
Key Concepts Covered
- Autoencoder architecture (encoder, bottleneck, decoder)
- Information bottleneck principle
- Training on normal only (unsupervised anomaly detection)
- Reconstruction loss (MSE reduction='none' for per-sample)
- Threshold tuning on validation set
- AUC-PR vs AUC-ROC for imbalanced data
- Latent space visualization with t-SNE
- Full unsupervised learning pipeline