Skip to content

Repository files navigation

Fraud Shield AI

Project Overview

Fraud Shield AI is a leakage-aware transaction risk platform for payment-fraud scoring. It converts chronologically ordered card transactions into deterministic behavioral features, defines immutable temporal partitions, learns preprocessing state from training rows only, and serves a validation-selected hybrid model through authenticated HTTP inference and browser review interfaces.

The executable codebase provides:

  • chunked CSV ingestion and transformation;
  • causal per-card feature computation with portable state;
  • fingerprinted chronological train, validation, and out-of-time holdout boundaries;
  • train-fitted missing-value imputation, outlier clipping, scaling, frequency encoding, and sparse one-hot encoding;
  • mutually exclusive class weighting, random under-sampling, and mixed-data SMOTENC controls restricted to training rows;
  • persisted sparse model-data partitions bound to raw, feature, split, and preprocessing fingerprints;
  • class-weighted logistic regression and random forest classifiers plus histogram-based XGBoost;
  • a feedforward neural network over static engineered features;
  • a unidirectional LSTM over strictly prior same-card transaction sequences;
  • a validation-optimized log-odds fusion of XGBoost, FNN, and LSTM probabilities;
  • warm prepared-feature inference with frozen-threshold fraud decisions;
  • a process-lifetime FastAPI runtime with health, single/batch prediction, and reviewer-feedback endpoints;
  • a compact fingerprinted inference payload that excludes raw datasets and training matrices;
  • a non-root multi-stage container with health checks and persistent-volume support;
  • a Vercel web console that proxies protected inference without disclosing backend credentials;
  • GitHub Actions validation, container smoke testing, and gated deployment hooks;
  • feature and prediction drift monitoring using PSI, Kolmogorov-Smirnov, and Wasserstein statistics;
  • deterministic random search against an isolated chronological validation set;
  • validation-derived F2 decision thresholds and holdout evaluation centered on fraud recall, precision, and average precision;
  • integrity-bound estimator reports and a cross-model evaluation registry;
  • deterministic exploratory profiling and visualization;
  • validation of time ordering, coordinates, currency precision, timestamp ties, state continuity, label independence, artifact integrity, and fitting scope.

The repository contains fitted classical, neural, and hybrid estimators with validation-selected decision thresholds. Its operational outputs include feature-enriched transaction streams, causal velocity state, a chronological split manifest, a JSON-serialized preprocessing contract, imbalance-control metadata, registered sparse float32 partitions, a causal per-card sequence index, native or restricted-load estimator artifacts, drift references, latency measurements, model reports, evaluation matrices, a local Streamlit console, and a containerized public inference surface. Both interfaces validate raw manual or uploaded transactions, reproduce causal static and sequential context, explain model evidence, and persist explicit reviewer feedback.

The canonical production interface is https://fraudai.yusufadamu.dev. Its browser calls same-origin Vercel functions, which add the protected backend credential server-side and forward requests to the Render inference service.

Documentation map

Manual Scope
README.md System architecture, feature and preprocessing schemas, classifier contracts, evaluation, monitoring, application runtime, setup, and verification.
data/README.md Immutable raw dataset identity, schema, constraints, temporal boundaries, provenance status, and handling rules.
data/processed/README.md Generated feature, state, partition, preprocessing, sparse matrix, and sequence artifact contracts.
artifacts/README.md Estimator, report, prediction, drift, latency, application context, feedback, integrity, and retention registry.
app/README.md FastAPI and Streamlit input, causal scoring, explanation, feedback, launch, and security contracts.
deployment/README.md Container payload, Render/Vercel configuration, environment, CI/CD, routing, rollback, and operations.
web/README.md Static interface, server-side proxy, browser input, feedback, security headers, and Vercel contract.

Repository layout

FraudShield/
|-- .github/workflows/deploy.yml
|-- data/
|   |-- fraudTrain.csv
|   |-- fraudTest.csv
|   `-- processed/
|       `-- model_data/
|-- src/
|   |-- features.py
|   |-- preprocessing.py
|   |-- eda.py
|   |-- utils.py
|   `-- models/
|-- artifacts/
|   |-- models/
|   `-- app/
|-- app/
|   |-- api.py
|   |-- main.py
|   |-- scoring.py
|   |-- feedback.py
|   `-- serve.py
|-- deployment/
|   |-- runtime/
|   `-- smoke_transaction.json
|-- web/
|   |-- api/
|   |-- index.html
|   |-- app.js
|   `-- vercel.json
|-- notebooks/
|-- scripts/
|-- tests/
|-- Dockerfile
|-- docker-compose.yml
|-- render.yaml
|-- requirements-api.txt
|-- requirements.txt
`-- .streamlit/config.toml

Design and performance objectives

Objective System behavior
Fraud detection quality Produces behavioral signals intended for recall-, precision-, and PR-AUC-oriented classifiers rather than accuracy-only evaluation.
Leakage prevention Excludes the active transaction and all same-card transactions sharing its timestamp from prior-behavior features.
Determinism Uses explicit window boundaries, integer-cent accumulation, stable timestamp handling, ordered transaction-key fingerprints, fixed random seeds, and digest-protected JSON artifacts.
Scalability Reads CSV input in configurable chunks; feature state scales with retained card histories, while fit_csv stores numeric fitting values in a temporary disk-backed matrix and keeps only categorical aggregates in memory.
Stream continuity Carries per-card state across sequential files so known cards do not receive artificial empty histories at partition boundaries.
Sequence causality Represents each transaction with the current row and a bounded chain of strictly earlier same-card rows; future rows and labels never enter a sequence.
Evaluation integrity Fits transformation statistics and applies sampling only to the chronological training partition; validation and holdout prevalence remain unchanged.
Model selection integrity Ranks candidates by validation average precision, freezes an F2 threshold from validation probabilities, and evaluates only the winning estimator on the holdout.
Artifact traceability Binds every model report to its estimator digest, model-data manifest, feature schema, parameters, dependency versions, and random seed.
Data integrity Rejects missing card identifiers, invalid timestamps, non-finite amounts, unsupported currency precision, invalid coordinates, and per-card time reversals.
Privacy EDA samples exclude names, streets, raw card identifiers, birth dates, and transaction identifiers. Feature-enriched CSVs retain source columns and require the same controls as raw data.
Application boundary Keeps Streamlit loopback-only; protects production prediction and feedback with a constant-time API-key check; terminates public TLS at Vercel and Render; and prevents reviewer feedback from changing active models automatically.

System Architecture & Pipeline Flow

Runtime components

Path Responsibility
src/features.py Geospatial calculations, causal velocity features, state serialization, chunked CSV processing, and the feature-generation CLI.
src/preprocessing.py Chronological split manifests, train-fitted sparse transformation, JSON preprocessing artifacts, imbalance controls, and the preprocessing CLI.
src/models/data.py Raw-fingerprint verification, feature-stream generation, frozen preprocessing, sparse partition persistence, and model-data integrity checks.
src/models/logistic.py Sparse class-weighted logistic classifier factory.
src/models/random_forest.py Class-weighted random-forest classifier factory.
src/models/xgboost_model.py Histogram-based XGBoost classifier factory with validation early stopping.
src/models/evaluation.py Average precision, PR-AUC, calibration metrics, operating metrics, and validation-only F2 threshold selection.
src/models/search.py Deterministic random parameter sampling, candidate fitting, winner selection, estimator persistence, and evaluation registries.
src/models/train.py Model-data preparation, per-model fitting, complete classifier execution, and report consolidation CLI.
src/models/deep_common.py Deterministic PyTorch configuration, training-only endpoint sampling, sparse minibatch materialization, and restricted neural weight persistence.
src/models/fnn.py Static feedforward architecture, optimization loop, early stopping, inference, and artifact loading.
src/models/sequences.py Digest-bound previous-transaction pointers, cross-partition sparse access, chronological padding, and sequence minibatches.
src/models/lstm.py Unidirectional packed-sequence LSTM, optimization loop, early stopping, inference, and artifact loading.
src/models/deep_train.py Sequence preparation, neural fitting, and combined classifier comparison CLI.
src/models/hybrid.py Validation-only probability fusion, component lineage verification, warm prepared-feature inference, latency measurement, and operational trade-off reporting.
src/models/drift.py Quantile-binned feature PSI, prediction-distribution statistics, reference persistence, and controlled drift simulation.
src/models/hybrid_train.py Hybrid optimization, latency measurement, drift simulation, and six-model report consolidation CLI.
app/scoring.py Raw transaction validation, compact online sequence context, session-isolated causal state, hybrid scoring, and local XGBoost evidence.
app/feedback.py Concurrency-safe SQLite reviewer feedback and controlled export.
app/main.py Streamlit manual scoring, batch review, model explanation, monitoring, and feedback interface.
app/api.py FastAPI configuration, process-lifetime artifact loading, CORS, API-key enforcement, health, single/batch prediction, and feedback endpoints.
app/serve.py One-worker Uvicorn process configuration for container and local HTTP execution.
scripts/package_runtime.py Compact runtime artifact copying, manifest generation, byte-size registration, and SHA-256 verification.
deployment/runtime/ Version-controlled, manifest-bound inference payload used by cloud and container builds.
Dockerfile Multi-stage CPU inference image, non-root runtime, health check, and minimal production dependency installation.
docker-compose.yml Local API orchestration with a persistent SQLite volume.
render.yaml Render Docker service, health path, environment contract, and deploy-control defaults.
web/ Vercel static console and same-origin serverless API proxy.
.github/workflows/deploy.yml Python validation, runtime verification, container inference smoke test, and gated production deployment.
src/utils.py Atomic JSON persistence, stable JSON digests, file hashing, and runtime dependency capture.
src/eda.py Exact chunked profiling, deterministic sampling, aggregate quality checks, and pre-sampling feature computation.
notebooks/01_eda.ipynb Correlation, imbalance, amount, distance, temporal, and geographic visualizations using outputs from src/eda.py.
scripts/validate_notebook.py Headless execution of notebook code cells with optional figure export for verification.
tests/test_features.py Feature-contract tests covering causal boundaries, timestamp ties, state continuation, geography, currency precision, and chunk invariance.
tests/test_eda.py Profiling, sampling, privacy, aggregation, and source-fingerprint tests.
tests/test_preprocessing.py Temporal partition, train-only fitting, artifact-integrity, encoding, class-weighting, and resampling tests.
tests/test_models.py Probability, threshold, estimator-factory, search-determinism, report-integrity, and model-artifact tests.
tests/test_deep_models.py Neural shapes, training sampling, cross-partition sequence causality, restricted weight loading, and neural search tests.
tests/test_hybrid.py Fusion constraints, warm inference decisions, latency contracts, drift separation, and detector persistence tests.
tests/test_app.py Raw input, event-clock, card-precision, session state, sequence causality, and feedback persistence tests.
tests/test_api.py HTTP health, authentication, single/batch request, input guard, CORS, and feedback contracts.
data/ Immutable raw CSV inputs and the processed/ destination for generated feature, state, partition, and preprocessing artifacts.

Data lineage

data/fraudTrain.csv                         data/fraudTest.csv
        |                                            |
        +---------- fingerprint and scan ------------+
        |                                            |
        |                             chronological_split_manifest
        |                             - whole unix_time buckets
        |                             - train/validation row boundaries
        |                             - isolated out-of-time holdout
        |                                            |
        v                                            v
add_geospatial_features(...)              causal continuation with
RollingFeatureState.transform_chunk(...)  development velocity state
        |                                            |
        v                                            v
fraudTrain_features.csv.gz                fraudTest_features.csv.gz
        |                                            |
        +-- training rows ---------------------------+
        |       fit FraudPreprocessor once           |
        |       - median imputation                   |
        |       - log1p and quantile clipping         |
        |       - standard scaling                    |
        |       - frequency and nominal vocabularies  |
        |                    |                       |
        |                    v                       |
        |       fraud_preprocessor.json.gz            |
        |                    |                       |
        +-- train ----------+-- validation ----------+-- holdout
             |                       |                     |
             v                       v                     v
       frozen transform       frozen transform      frozen transform
             |                       |                     |
             v                       v                     v
       imbalance control       unchanged class       unchanged class
       train rows only         prevalence            prevalence
             |                       |                     |
             +-----------------------+---------------------+
                                     |
                                     v
                        registered sparse CSR partitions
                                     |
                  +-------------+------------+-------------+
                  |             |            |             |
                  v             v            v             v
          logistic/forest    XGBoost     static FNN   previous-row index
                                                            |
                                                            v
                                                     causal card LSTM
                  |             |            |             |
                  +-------------+------------+-------------+
                                      |
                                      v
                     validation-only log-odds fusion
                                      |
                                      v
                       validation F2 threshold
                                      |
                                      v
                  warm risk scoring and fraud decision
                                      |
                         +------------+------------+
                         |                         |
                         v                         v
                holdout evaluation       feature/score drift
                                             monitoring
                         |
                         v
              compact online sequence context
                         |
                         v
              compact deployment/runtime bundle
                         |
                         v
                FastAPI process-lifetime load
                         |
              +----------+-----------+
              |                      |
              v                      v
       /predict single/batch      /feedback
              |                      |
              v                      v
       Vercel server proxy       SQLite ledger
              |
              v
   fraudai.yusufadamu.dev browser console

The loopback Streamlit console consumes the same compact online context and model artifacts directly. Its session state is isolated from the stateless HTTP request boundary.

process_csv does not inspect is_fraud; changing or removing the label does not change engineered features. The output retains every source column except the redundant export index by default, then appends the registered feature columns below.

FraudPreprocessor.fit and FraudPreprocessor.fit_csv require partition="train". Passing split_manifest=manifest additionally binds fitting to the registered row count, time range, target counts, ordered transaction keys, and manifest digest. Frozen statistics are reused for validation and holdout transformation; those partitions cannot extend vocabularies, change frequencies, alter clipping bounds, or influence scaling. prepare_training_batch accepts only the exact fitted partition and enforces the same training-only scope for class weighting and resampling.

Feature-stream generation

Run commands from the FraudShield directory.

Transform the development stream and persist its terminal state:

python -m src.features `
  --input data/fraudTrain.csv `
  --output data/processed/fraudTrain_features.csv.gz `
  --state-out data/processed/train_velocity_state.json.gz

Continue feature computation into the chronological evaluation stream:

python -m src.features `
  --input data/fraudTest.csv `
  --output data/processed/fraudTest_features.csv.gz `
  --state-in data/processed/train_velocity_state.json.gz `
  --state-out data/processed/test_velocity_state.json.gz

Existing output paths are rejected unless --force is supplied. Each CSV or state file is written through a temporary file and atomically replaced after successful serialization. Feature output and state output are committed separately.

Partition and preprocessing controls

Create the digest-protected chronological split manifest from the immutable raw files:

python -m src.preprocessing split `
  --development data/fraudTrain.csv `
  --holdout data/fraudTest.csv `
  --output data/processed/split_manifest.json

The default validation_fraction=0.20 places the final 20% of development rows in validation without dividing a shared unix_time bucket. The holdout must begin strictly after the development stream. File sizes, SHA-256 fingerprints, schemas, boundaries, row counts, class counts, and fraud rates are recorded in the manifest.

Fit and persist preprocessing state from the manifest-defined training prefix of the feature-enriched development stream:

from src.eda import sha256_file
from src.preprocessing import FraudPreprocessor, load_split_manifest

manifest = load_split_manifest("data/processed/split_manifest.json")
feature_path = "data/processed/fraudTrain_features.csv.gz"
preprocessor = FraudPreprocessor().fit_csv(
    feature_path,
    partition="train",
    split_manifest=manifest,
    source_sha256=sha256_file(feature_path),
)
preprocessor.save("data/processed/fraud_preprocessor.json.gz")

Create the deterministic train-only imbalance comparison artifact:

python -m src.preprocessing imbalance-report `
  --split-manifest data/processed/split_manifest.json `
  --output data/processed/imbalance_strategy_report.json `
  --sampling-strategy 0.10 `
  --random-state 42

Output paths are write-once by default. Pass --force only when deliberate replacement of a reproducible artifact is required.

Feature Schema Registry

Default configuration:

Setting Value
Card identifier cc_num
Causal clock unix_time, whole seconds
Transaction amount amt, no more than two decimal places
Cardholder coordinates lat, long
Merchant coordinates merch_lat, merch_long
Rolling windows 3,600; 21,600; and 86,400 seconds
Invalid-coordinate policy raise
Earth radius 6,371.0088 km

For a transaction belonging to card c at time t, every rolling interval is left-inclusive and right-exclusive: t - window <= event_time < t.

Output column Type and unit Definition
distance_card_merchant_km float64, kilometers Great-circle distance between (lat, long) and (merch_lat, merch_long) using the Haversine formula.
cc_txn_count_prev_1h int64, transactions Count for card c in [t - 3600, t).
cc_amt_sum_prev_1h float64, currency units Sum of amt for card c in [t - 3600, t).
cc_txn_count_prev_6h int64, transactions Count for card c in [t - 21600, t).
cc_amt_sum_prev_6h float64, currency units Sum of amt for card c in [t - 21600, t).
cc_txn_count_prev_24h int64, transactions Count for card c in [t - 86400, t).
cc_amt_sum_prev_24h float64, currency units Sum of amt for card c in [t - 86400, t).
cc_txn_count_prior int64, transactions Count of all transactions for card c in timestamp buckets strictly earlier than t, without a time limit.
cc_amt_sum_prior float64, currency units Sum of amt across all strictly earlier timestamp buckets for card c, without a time limit.

Numeric and state invariants

Mechanism Contract
Currency scaling amt is converted to signed int64 cents before accumulation. Values that cannot be represented exactly at two-decimal currency precision are rejected. Rolling sums are exposed as float64 currency units.
Timestamp ties Rows sharing (cc_num, unix_time) receive identical prior-behavior features. Their aggregate becomes visible only to a strictly later timestamp.
Window boundary A bucket exactly at t - window is included; a bucket one second earlier is excluded.
Card isolation State is keyed by the string representation of cc_num; one card never contributes to another card's features.
Stream ordering Chunked transformation accepts interleaved cards but requires nondecreasing unix_time for each card across all chunks. A reversal raises ValueError.
Batch ordering In-memory batch transformation stably sorts by the causal clock for computation and restores the original positional order.
Rolling state Each card stores a pending timestamp bucket, one deque per configured window, cached rolling totals, and scalar all-prior totals.
State persistence RollingFeatureState serializes to JSON or gzip-compressed JSON with schema_version = 1; arbitrary-code pickle deserialization is not used.
State compatibility A loaded state must use the same column names, windows, and invalid-coordinate policy as the active FeatureConfig; a mismatch raises ValueError.
Partition continuity Supplying --state-in makes the next file a causal continuation. Cards absent from the state start with zero prior counts and spend.
Label independence is_fraud is neither required nor read by feature calculations.

Custom positive whole-second windows are supported. Output suffixes use Nh for whole hours, Nm for whole minutes, and Ns otherwise.

Preprocessing Schema Registry

FraudPreprocessor emits a SciPy CSR matrix with float32 values. Feature order is stored in the preprocessing artifact and protected by feature_schema_sha256. Direct identifiers and source fields not listed below, including cc_num, trans_num, names, street address, raw date of birth, raw timestamps, and is_fraud, are not emitted into the matrix.

Input group Registered fields Transformation and output contract
Numeric transaction and behavior amt, city_pop, distance, 1/6/24-hour counts and spend, all-prior count and spend Median imputation, log1p, training-quantile clipping at 0.5% and 99.5%, then training-mean standardization. One num__log1p_* column per field.
Derived numeric age_years Transaction date minus date of birth in mean solar years; median imputation, quantile clipping, and standardization.
Derived cyclical hour of day, day of week, month of year Sine/cosine pairs named num__hour_*, num__day_*, and num__month_*; quantile clipping and standardization use training statistics.
Low-cardinality nominal category, state Sparse one-hot columns with explicit __MISSING__ and __UNKNOWN__ levels. Vocabulary is fixed by training rows.
High-cardinality categorical merchant, city, job, zip Training relative frequency plus an unknown-level indicator per input: freq__<field> and freq__<field>__unknown.

Fitting and transformation invariants

Mechanism Contract
Fitting scope fit and fit_csv accept only partition="train". Validation and holdout rows cannot contribute preprocessing statistics.
Manifest binding Supplying split_manifest derives the training boundary and verifies row count, time endpoints, label counts, ordered transaction-key digest, and manifest digest. fit_csv also recomputes the feature CSV SHA-256 fingerprint.
Missing values Numeric medians and categorical missing tokens are learned or registered without using the target. Malformed non-null values remain validation errors.
Outliers Quantile bounds are learned after optional log1p transformation and are frozen for every later partition.
Unknown categories Unseen nominal values map to the registered __UNKNOWN__ one-hot level; unseen high-cardinality values receive frequency 0.0 and unknown indicator 1.0.
Output schema Numeric fields precede frequency fields, followed by nominal one-hot fields. The ordered names and schema digest are serialized with the artifact.
Artifact format JSON or gzip-compressed JSON, schema_version = 1, with content digest, configuration, numeric statistics, vocabularies, frequency mappings, fitted context, and dependency versions. Pickle deserialization is not used.
Immutability Calling transform, prepare_sampler_frame, or transform_sampler_frame does not change fitted statistics or vocabularies.

Imbalance controls

Exactly one ImbalanceConfig.strategy is applied to a training batch. Validation and holdout rows are transformed without class rebalancing.

Strategy Training behavior Default output ratio
none Preserves source rows and labels. Observed training prevalence.
class_weight Preserves rows and supplies balanced per-row weights computed from training labels. Observed training prevalence.
random_under Deterministically reduces majority rows with RandomUnderSampler; selected row positions are SHA-256 fingerprinted in metadata. Minority/majority = 0.10.
smotenc Applies SMOTENC to scaled continuous and frequency fields plus unencoded low-cardinality fields, then performs sparse one-hot encoding. Minority/majority = 0.10.

SMOTENC rejects a minority class with no more rows than k_neighbors. Default guards reject projections above 2,000,000 rows or 2,000,000,000 conservatively estimated dense working bytes. Every TrainingBatch records class counts before and after handling, random seed, ordered input and selection fingerprints, sampler class, dependency versions, schema digest, and the assertion that validation and holdout were not sampled.

TrainingBatch is a fixed-partition final-fit interface. It must not be supplied to cross-validation search because its preprocessing state and sampling decision already reflect the complete fitting partition. Cross-validation consumers must fit transformations and apply resampling independently inside each training fold while leaving each fold's validation rows untouched.

Classical Classifier Registry

Optimization and decision contract

Control Registered behavior
Candidate sampling ParameterSampler draws deterministic, nonrepeating parameter configurations from model-specific spaces using random_state=42.
Training scope Every candidate fits only the 1,037,340-row chronological training partition.
Class imbalance Logistic regression uses balanced class weights, random forest uses balanced per-tree weights, and XGBoost searches positive-class weights derived from the training ratio.
Candidate ranking Validation average precision is primary; validation recall and precision break exact ties. Accuracy is not a selection metric.
Boosting control XGBoost uses histogram trees, aucpr evaluation, and validation-based early stopping.
Threshold The winning model's threshold maximizes validation F2; ties favor recall, precision, then the higher threshold.
Holdout access Only the selected estimator is scored on holdout, using the frozen validation threshold. Holdout results do not alter parameters or thresholds.
Persistence Scikit-learn estimators use compressed Joblib for trusted internal use. XGBoost uses native JSON. Every report stores the estimator SHA-256 digest.

Registered evaluation

The current evaluation registry is generated from the immutable model-data manifest and reports the following out-of-time performance:

Classifier Validation AP Holdout AP Holdout PR-AUC Holdout recall Holdout precision Holdout FPR Frozen threshold
Logistic regression 0.601922 0.537643 0.537603 0.580420 0.359411 0.004008 0.870336
Random forest 0.943986 0.900815 0.900809 0.877855 0.743094 0.001176 0.273135
XGBoost 0.980621 0.965863 0.965858 0.945455 0.843945 0.000677 0.233010

Average precision is the non-interpolated weighted mean of precision over recall increments. pr_auc_trapezoidal is also recorded explicitly; the two measures are related but not interchangeable. Each report additionally contains ROC-AUC, Brier score, log loss, confusion counts, specificity, F1, F2, false-negative rate, alert rate, precision at recall targets, recall at precision targets, candidate parameters, and fit durations.

Model commands

Generate causal features, fit preprocessing on training rows, and persist all sparse partitions:

python -m src.models.train prepare-data

Optimize one classifier with its registered search count:

python -m src.models.train fit --model logistic_regression
python -m src.models.train fit --model random_forest
python -m src.models.train fit --model xgboost

Run all classifier searches in one process:

python -m src.models.train run-all

Verify independent model reports and rebuild the cross-model registry:

python -m src.models.train summarize

Model-data outputs are written under data/processed/model_data/; fitted estimators and reports are written under artifacts/models/. Existing registered outputs are rejected unless the global --force option is supplied before the subcommand. Generated transaction matrices and model artifacts are excluded from version control.

Neural Classifier Registry

Static FNN contract

The static network consumes the same 95 ordered features as the classical estimators. Sparse CSR rows are materialized only for the active minibatch. The registered architecture uses two GELU and LayerNorm hidden blocks, dropout, and a single fraud logit. Training uses AdamW, gradient clipping, weighted BCEWithLogitsLoss, all fraud endpoints, and a deterministic training-only negative sample refreshed by epoch.

Setting Registered value
Hidden widths 64, 32
Dropout 0.20
Batch size 2,048
Learning rate 0.001
Weight decay 0.00001
Training negative/fraud endpoint cap 40:1
Positive-loss multiplier 0.50 of sampled negative/fraud ratio
Selected epoch 6

Sequential LSTM contract

previous_transaction_index.npy stores one int32 pointer per transaction across training, validation, and holdout. A pointer is either -1 or strictly less than the active global row. Sequence batches follow the pointers backward, restore oldest-to-current order, and use packed lengths so padding is ignored. Validation endpoints may inherit training history, and holdout endpoints may inherit development history; neither partition can point forward. Targets are endpoint labels only and are never sequence inputs.

The registered LSTM projects each 95-feature row to 64 dimensions, processes up to 12 transactions through two unidirectional 64-unit recurrent layers, and emits one fraud logit from the final valid hidden state.

Setting Registered value
Sequence length 12 transactions
Input projection 64
Hidden size 64
Recurrent layers 2
Dropout 0.10
Batch size 1,024
Learning rate 0.0007
Weight decay 0.00001
Training negative/fraud endpoint cap 20:1
Positive-loss multiplier 1.00 of sampled negative/fraud ratio
Selected epoch 5

Complete classifier evaluation

Every row below uses the same frozen preprocessing schema, chronological partitions, validation average-precision selection rule, validation F2 threshold rule, and untouched out-of-time holdout. The hybrid candidate weights, blend space, and decision threshold are selected without holdout labels.

Classifier Holdout AP Precision Recall F2 FPR Frozen threshold
Logistic regression 0.537643 0.359411 0.580420 0.516855 0.004008 0.870336
Static FNN 0.850898 0.539591 0.873660 0.777400 0.002889 0.906579
Random forest 0.900815 0.743094 0.877855 0.847130 0.001176 0.273135
Causal LSTM 0.931596 0.562603 0.951049 0.835655 0.002865 0.774295
XGBoost 0.965863 0.843945 0.945455 0.923245 0.000677 0.233010
Hybrid 0.976708 0.879281 0.957576 0.940821 0.000509 0.472196

These values use each estimator's frozen validation-selected threshold against the same 555,719-row out-of-time holdout. The hybrid has the strongest registered holdout ranking, recall, precision, F2, and false-positive rate. It detects 2,054 of 2,145 fraud rows and produces 282 false positives. The complete reports also retain validation AP, holdout PR-AUC, alert rate, calibration, ROC-AUC, confusion counts, precision-at-recall, and recall-at-precision.

Neural commands

Create and verify the global causal pointer index:

python -m src.models.deep_train prepare-sequences

Optimize each neural classifier:

python -m src.models.deep_train --device auto fit --model fnn
python -m src.models.deep_train --device auto fit --model lstm

Verify all five reports and rebuild the combined registry:

python -m src.models.deep_train summarize

Neural weights use PyTorch tensor artifacts loaded with weights_only=True. Reports bind each weight file to its SHA-256 digest, model configuration, model-data lineage, feature schema, search parameters, epoch metrics, runtime dependencies, threshold, and holdout metrics. The LSTM report additionally binds the sequence-index manifest.

Hybrid Inference and Monitoring Registry

Fusion contract

The hybrid consumes aligned probabilities from the registered XGBoost, FNN, and causal LSTM artifacts. Candidate weights are constrained to the probability simplex with a 5% minimum contribution from every component. Thirty-two deterministic weight vectors are evaluated in both probability and log-odds space, producing 64 candidates. Validation average precision ranks candidates; validation F2, recall, and precision break ties. The holdout is scored only after the fusion rule and threshold are frozen.

Setting Registered value
Blend space Log-odds
XGBoost weight 0.5600
FNN weight 0.0925
LSTM weight 0.3475
Decision threshold 0.472196
Threshold objective Validation F2
Validation AP 0.986636
Holdout AP 0.976708

HybridInferenceEngine.load verifies the content digests of the hybrid configuration and all component reports, verifies estimator fingerprints, loads the component models once, and places neural modules in evaluation mode. predict_prepared accepts aligned static features, length-12 causal sequences, and sequence lengths. It returns the three component probabilities, fused fraud probability, and a Boolean decision using the frozen threshold. Neural execution runs under torch.inference_mode().

Prepared-feature latency

The registered benchmark uses a six-thread CPU runtime, three warm-up calls, and 20 measured calls per batch size. Models are already loaded and inputs are already transformed; raw parsing, feature engineering, preprocessing, sequence assembly, process startup, and network overhead are outside the measurement scope.

Classifier Batch-1 p50 (ms) Batch-1 p95 (ms) Batch-256 p50 per transaction (ms) Batch-256 p50 throughput (transactions/s)
Logistic regression 0.120 0.132 0.000512 1,954,198
XGBoost 0.563 0.665 0.005430 184,146
Static FNN 0.449 0.511 0.002380 420,120
Causal LSTM 1.391 2.031 0.014886 67,178
Hybrid 2.771 3.745 0.032876 30,417
Random forest 33.665 38.256 0.113780 8,789

Drift contract

DriftDetector freezes both feature and hybrid-score references from the same chronological validation window. It samples at most 100,000 feature rows and 10,000 probabilities with a fixed seed. Each of the 95 transformed features is monitored with quantile-binned population stability index (PSI). Hybrid scores additionally report PSI, a two-sample Kolmogorov-Smirnov statistic and p-value, and first Wasserstein distance.

PSI Status
< 0.10 stable
0.10 to < 0.25 warning
>= 0.25 critical

The reference validation window is stable by construction. The out-of-time holdout reports critical feature drift in calendar and lifetime-cumulative fields while its hybrid-score PSI remains stable at 0.002534. The controlled simulation adds 1.5 standardized units to amount, distance, 24-hour transaction count, and 24-hour spend plus a 0.75 log-odds score shift; both feature and prediction monitoring classify it as critical.

Hybrid commands

Optimize fusion weights and persist the frozen configuration:

python -m src.models.hybrid_train --device cpu fit

Measure all six warm classifiers on prepared inputs:

python -m src.models.hybrid_train --device cpu benchmark

Create drift references and evaluate registered and controlled windows:

python -m src.models.hybrid_train simulate-drift

Rebuild the quality and operational trade-off matrices:

python -m src.models.hybrid_train summarize

Run the complete hybrid, latency, drift, and consolidation workflow:

python -m src.models.hybrid_train --device cpu run-all

Outputs are stored under artifacts/models/: hybrid_config.json, hybrid_report.json, hybrid_probabilities.npz, latency_benchmark.json, drift_detector.json, drift_simulation_report.json, hybrid_evaluation_matrix.json, and operational_tradeoff_matrix.json. JSON artifacts are content-digest protected, and the hybrid report fingerprints its prediction cache and every component lineage.

Application and Production Inference Runtime

Interface registry

Interface Address Operational contract
Public web console https://fraudai.yusufadamu.dev Vercel-hosted manual and CSV batch scoring, hybrid explanations, and reviewer controls. Browser requests remain same-origin.
Production API https://fraudshield-ai-api.onrender.com behind the Vercel proxy Process-lifetime FastAPI model loading, authenticated prediction and feedback, compact registered artifacts, and platform health checks.
Local Streamlit console http://127.0.0.1:8501 Loopback-only manual scoring, batch review, monitoring summaries, feedback export, and mutable per-browser causal sessions.
Local container API http://127.0.0.1:8000 Docker Compose replication of the production backend with a named SQLite volume.

The production request boundary is stateless. Each /predict request starts from an independent copy of the registered terminal velocity and sequence context; rows inside one batch are processed in submitted order and may contribute causal history to later timestamps within that batch. No request can mutate another caller's behavioral state. Streamlit retains optional session-local continuation because it is an analyst-controlled loopback workflow.

HTTP API contract

Method and path Authentication Request Response
GET /health Public None Readiness, API version, release identifier, device, batch ceiling, and hybrid configuration digest.
POST /predict X-API-Key when configured One transaction object or {"transactions": [...]} with up to the configured row ceiling. Uniform count and predictions envelope containing hybrid/component probabilities, decision, context, behavioral values, and local XGBoost evidence.
POST /feedback X-API-Key when configured Complete prediction record plus confirm_fraud or false_positive. Idempotent reviewer-record acknowledgement.
GET /docs Public None Generated OpenAPI exploration surface. Production operators can restrict this path at the platform firewall if required.

FRAUDSHIELD_API_KEY is compared in constant time. The public browser never receives it: Vercel functions under web/api/ read BACKEND_API_KEY from server-side environment state and attach it only to the Render request. CORS accepts explicit configured origins and does not enable credentialed wildcard access.

Application input schema

Required raw fields are trans_date_trans_time, cc_num, merchant, category, amt, city, state, zip, lat, long, city_pop, job, dob, merch_lat, and merch_long. trans_num and unix_time are optional. Missing transaction identifiers are generated deterministically. Missing causal timestamps are derived from the display time using the dataset's documented seven-year clock offset. Card and ZIP identifiers are strict strings; numeric card input is rejected before feature computation to prevent irreversible precision loss.

The runtime calculates Haversine distance, velocity, cumulative behavior, frozen preprocessing, and causal LSTM context internally. XGBoost, FNN, and LSTM component probabilities feed the registered 56% / 9.25% / 34.75% log-odds fusion. Explanations show component consensus, behavioral context, and the eight largest absolute XGBoost log-odds contributions. XGBoost contributions describe that component and are not presented as a complete attribution of the nonlinear hybrid.

Feedback persistence

Confirm Fraud and False Positive write idempotently to SQLite. The container path is /var/lib/fraudshield/feedback.sqlite3; Docker Compose mounts a named volume at its parent directory. The public Render service currently uses the free instance class without a persistent disk, so its feedback ledger is instance-local and can be lost during replacement or rebuild. Durable production retention requires an eligible Render plan with a disk mounted at /var/lib/fraudshield.

The ledger stores prediction lineage, submitted values, engineered behavior, component scores, final risk, threshold, decision, sequence depth, and reviewer label. Feedback does not modify the active model automatically. The Streamlit sidebar can export a controlled CSV intake for a separately governed retraining workflow.

Runtime environment

Variable Consumer Required behavior
FRAUDSHIELD_API_KEY FastAPI Shared random secret for /predict and /feedback; required in public operation.
FRAUDSHIELD_ALLOWED_ORIGINS FastAPI Comma-separated exact origins. Production uses https://fraudai.yusufadamu.dev.
FRAUDSHIELD_PROJECT_ROOT FastAPI Root containing the compact artifacts/ and data/processed/ bundle. The image sets /opt/fraudshield/runtime.
FRAUDSHIELD_FEEDBACK_DB FastAPI SQLite path. The image sets /var/lib/fraudshield/feedback.sqlite3.
FRAUDSHIELD_MAX_BATCH_ROWS FastAPI Integer from 1 through 10,000; production defaults to 1,000.
FRAUDSHIELD_DEVICE FastAPI cpu, cuda, or auto; the production image uses cpu.
FRAUDSHIELD_VERIFY_SOURCE_ARTIFACTS FastAPI 0 for the compact bundle; 1 only when full feature streams are present.
BACKEND_API_URL Vercel functions https://fraudshield-ai-api.onrender.com
BACKEND_API_KEY Vercel functions Same value as FRAUDSHIELD_API_KEY; never use a public client prefix.

Compact runtime payload

The deployment payload contains only XGBoost, FNN, LSTM, their registered reports, the hybrid configuration, the frozen preprocessor, terminal velocity state, and compact sequence continuation. Raw CSVs, sparse training partitions, prediction caches, and training-only estimators are excluded.

Build and verify it from registered local artifacts:

python -m scripts.package_runtime build `
  --project-root . `
  --bundle-root deployment/runtime `
  --force
python -m scripts.package_runtime verify --bundle-root deployment/runtime
python -m app.scoring verify-runtime `
  --project-root deployment/runtime `
  --device cpu `
  --skip-source-verification

deployment/runtime/runtime_manifest.json registers 11 files totaling 2,829,862 bytes with payload SHA-256 FC447EAB5EE6D4208B7542BD015E8F28257494357C81735B49A0547EC41C48A7. JSON artifacts use canonical LF bytes and the complete payload is excluded from Git line-ending transformation so its byte-level fingerprints remain stable across operating systems. Model, report, preprocessor, sequence-context, and terminal-state loaders then enforce their native integrity contracts during API startup.

Local application commands

Launch the analytical Streamlit interface:

python -m app.scoring verify-runtime --project-root . --device cpu
python -m streamlit run app/main.py --server.address 127.0.0.1 --server.port 8501

Open http://127.0.0.1:8501. If localhost does not resolve to the active listener, use the explicit loopback address.

Run the production backend with Docker Compose:

Copy-Item .env.example .env
# Replace the example secret before starting the service.
docker compose up --build

Verify readiness:

Invoke-RestMethod http://127.0.0.1:8000/health

Run the production backend directly from Python:

$env:FRAUDSHIELD_PROJECT_ROOT = (Resolve-Path deployment/runtime)
$env:FRAUDSHIELD_FEEDBACK_DB = (Join-Path (Resolve-Path .) "state/feedback.sqlite3")
$env:FRAUDSHIELD_API_KEY = "replace-with-a-random-secret"
$env:FRAUDSHIELD_ALLOWED_ORIGINS = "http://127.0.0.1:3000"
$env:PORT = "8000"
python -m app.serve

The current context contains 999 cards, 95 transformed features, and up to 11 prior vectors for a maximum sequence length of 12. See app/README.md, deployment/README.md, and web/README.md for endpoint, state, platform, and browser contracts.

Cloud Routing and CI/CD

Production routing

Browser
  |
  | HTTPS fraudai.yusufadamu.dev
  v
Vercel static interface
  |
  | same-origin /api/{health,predict,feedback}
  v
Vercel Node function
  |
  | HTTPS + server-side X-API-Key
  v
Render Docker service
  |
  +--> process-lifetime hybrid runtime
  `--> /var/lib/fraudshield/feedback.sqlite3

Vercel owns the public custom-domain certificate and routes the fraudai CNAME to the web project. Render provides a separate TLS service origin consumed only by the server-side proxy. The backend CORS list still includes the canonical web origin for controlled direct browser diagnostics.

render.yaml points Render at TechCeo/FraudShield-AI, the repository-root Dockerfile, /health, and the production environment contract. The Vercel project uses the same repository with web as its root directory. web/vercel.json applies a restrictive Content Security Policy, disables framing, restricts browser capabilities, and marks API responses non-cacheable.

Automated deployment gates

.github/workflows/deploy.yml runs on pull requests, pushes to main, and manual dispatch. Its gates are:

  1. install the declared Python environment and run the complete test suite;
  2. verify the compact manifest and load every registered production model;
  3. build the container, wait for readiness, and execute a real protected prediction;
  4. on main, trigger Render and wait until /health.release equals the Git commit;
  5. trigger Vercel and wait until the custom-domain proxy exposes the same release;
  6. execute a real prediction through the public same-origin route and validate the response contract.

The production GitHub environment requires:

Type Name Value
Secret RENDER_DEPLOY_HOOK_URL Render service deploy hook for main.
Secret VERCEL_DEPLOY_HOOK_URL Vercel deploy hook bound to main.
Variable BACKEND_HEALTH_URL Render HTTPS origin plus /health.

Render and Vercel Git auto-deployment are disabled in favor of the post-validation hooks. A failed test, artifact check, container startup, protected prediction, release-identity check, or routed authenticated prediction prevents the release from being reported as healthy.

Rollback and recovery

  • Redeploy a known-good Git commit through the corresponding Render and Vercel deployment histories.
  • Keep API and frontend releases aligned; the proxied /api/health release is the authoritative cross-service check.
  • Preserve or snapshot the mounted SQLite disk before replacing a service with reviewer data.
  • Never rebuild registered model artifacts during deployment. Model replacement begins with a new fingerprinted runtime bundle and must pass all validation gates.
  • If the backend is unavailable, Vercel returns a bounded 502 or 504 response without disclosing service credentials or internal exception details.

Environment Setup & Verification

Prerequisites

  • Python 3.12 or later; the verified local runtime is Python 3.13.4
  • fraudTrain.csv and fraudTest.csv under data/
  • Sufficient local storage for raw files, generated feature streams, and serialized state
  • Docker Desktop or another Docker Engine for production-image replication
  • Node.js 22 or later for local validation of the Vercel functions

Installation

  1. Change to the project directory:

    cd C:\path\to\Capstone\FraudShield
  2. Create an isolated Python environment:

    python -m venv .venv
  3. Activate the environment:

    .\.venv\Scripts\Activate.ps1

    On macOS or Linux:

    source .venv/bin/activate
  4. Install the declared dependencies:

    python -m pip install --upgrade pip
    python -m pip install -r requirements.txt

Automated verification

Run the feature-contract suite:

python -m pytest tests/test_features.py -q --basetemp .pytest_tmp_features

Run the preprocessing-contract suite:

python -m pytest tests/test_preprocessing.py -q --basetemp .pytest_tmp_preprocessing

Run the model-contract suite:

python -m pytest tests/test_models.py -q --basetemp .pytest_tmp_models

Run the neural-contract suite:

python -m pytest tests/test_deep_models.py -q --basetemp .pytest_tmp_deep

Run the hybrid inference and drift-contract suite:

python -m pytest tests/test_hybrid.py -q --basetemp .pytest_tmp_hybrid

Run the application scoring and feedback-contract suite:

python -m pytest tests/test_app.py -q --basetemp .pytest_tmp_app

Run the production API contract suite:

python -m pytest tests/test_api.py -q --basetemp .pytest_tmp_api

Run all automated tests:

python -m pytest -q --basetemp .pytest_tmp_all

The complete suite contains 64 tests: the 54 data, feature, preprocessing, model, neural, hybrid, and application contracts, eight production API contracts, and two cross-platform runtime-package integrity contracts. This is the authoritative CI command.

Verify the version-controlled inference payload:

python -m scripts.package_runtime verify --bundle-root deployment/runtime
python -m app.scoring verify-runtime `
  --project-root deployment/runtime `
  --device cpu `
  --skip-source-verification

Build and start the exact production container:

docker build --tag fraudshield-api:local .
docker compose up

Validate every notebook code cell against the full training dataset with a headless plotting backend:

python scripts/validate_notebook.py notebooks/01_eda.ipynb

Confirm the feature CLI surface without writing output files:

python -m src.features --help

Confirm the preprocessing CLI surface without writing output files:

python -m src.preprocessing --help

Confirm the classifier CLI surface without writing output files:

python -m src.models.train --help

Confirm the neural CLI surface without writing output files:

python -m src.models.deep_train --help

Confirm the hybrid CLI surface without writing output files:

python -m src.models.hybrid_train --help

Verify application artifacts without starting the web server:

python -m app.scoring verify-runtime --project-root . --device cpu

Start the application:

python -m streamlit run app/main.py --server.address 127.0.0.1 --server.port 8501

A successful verification command exits with status code 0. Test failures, schema violations, artifact-digest mismatches, invalid fitting scope, timestamp reversals, invalid coordinates, and unsupported currency precision produce nonzero exits or raised exceptions.

About

Real-time, end-to-end AI fraud detection system leveraging hybrid machine learning and deep learning architectures to ingest transactional streams, compute stateful geospatial/velocity metrics, and flag high-risk transactions with low latency.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages