AI/ML-Powered Container Shipment Risk Scoring System
Built with XGBoost ยท SHAP Explainability ยท Isolation Forest Anomaly Detection ยท React Dashboard
- Overview
- Key Features
- Architecture
- Tech Stack
- Quick Start
- Project Structure
- Usage Workflow
- Expected CSV Format
- ML Pipeline Deep Dive
- Feature Engineering
- SHAP Explainability
- API Reference
- Frontend Components
- Configuration & Environment
- Troubleshooting
- Contributing
- License
SmartContainer Risk Engine (SCRE) is a production-grade, AI-powered risk scoring system designed for customs and container shipment screening. It automatically identifies high-risk (Critical) containers from shipment data using advanced machine learning, providing per-container plain-English explanations for every flagged shipment.
The system combines supervised learning (XGBoost) with unsupervised anomaly detection (Isolation Forest) and statistical analysis (Benford's Law, Z-scores) to deliver a robust, multi-layered risk assessment that goes far beyond simple rule-based screening.
Traditional customs screening relies on manual rule-based systems that are:
- Static โ unable to adapt to evolving smuggling patterns
- Opaque โ provide no explanation for why a container is flagged
- Inaccurate โ high false-positive rates lead to inspector fatigue
SCRE addresses all three with an ML-first approach, automatic threshold optimization, and SHAP-powered explainability for every single prediction.
| Feature | Description |
|---|---|
| ๐ค XGBoost Classification | Gradient-boosted tree model with early stopping and hyperparameter tuning for high-accuracy risk classification |
| ๐ Isolation Forest | Unsupervised anomaly detection that identifies statistical outliers across all features, feeding as an additional signal |
| โ๏ธ SMOTE Oversampling | Synthetically balances the minority class (Critical) to prevent the model from ignoring rare but important violations |
| ๐ SHAP Explainability | TreeExplainer generates per-container, plain-English explanations โ every prediction is interpretable |
| ๐ Benford's Law Analysis | Detects fabricated declared values by comparing first-digit distributions against the expected mathematical pattern |
| ๐ฏ Optimal Threshold Tuning | Automatically finds the classification threshold that maximizes recall while maintaining precision โฅ 72% |
| ๐ 5-Fold Cross-Validation | Honest, unbiased metric estimation via stratified k-fold CV on the training set |
| ๐ซ Zero Data Leakage | Strict train/test split โ all feature statistics, encodings, and reputation scores are computed exclusively on training data |
| ๐ญ 24 Engineered Features | Weight anomalies, unit value Z-scores, dwell time deviations, temporal patterns, route rarity, importer/exporter reputation, and more |
| ๐ฅ๏ธ Production React Dashboard | Step-by-step workflow UI with real-time API status, interactive charts, sortable/filterable tables, and CSV export |
| ๐ณ Docker Compose | One-command deployment with persistent model storage and live-reload development |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SmartContainer Risk Engine โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Frontend (React) โ Backend (FastAPI) โ
โ :3000 โ :8000 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ App.jsx โ โ โ main.py (FastAPI Router) โ โ
โ โ โโ TrainPanel โโโโโโบโ โ โโ /api/health โ โ
โ โ โโ PredictPanel โ โ โ โโ /api/train โ โ
โ โ โโ MetricsPanel โ โ โ โโ /api/predict โ โ
โ โ โโ Dashboard โ โ โ โโ /api/metrics โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ โโ /api/download โ โ
โ โ โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ โ
โ โ api.js (Axios) โ โ โโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ HTTP + FormData โ โ โ model.py (ML Pipeline) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ โโ Label normalization โ โ
โ โ โ โโ Stratified train/test split โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ โโ SMOTE oversampling โ โ
โ โ Recharts โ โ โ โโ Isolation Forest โ โ
โ โ โโ PieChart โ โ โ โโ XGBoost training โ โ
โ โ โโ BarChart โ โ โ โโ 5-fold cross-validation โ โ
โ โ โโ RadarChart โ โ โ โโ Threshold optimization โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ โโ SHAP explainer โ โ
โ โ โ โโ Artifact persistence โ โ
โ โ โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โ โโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ features.py (Feature Engine) โ โ
โ โ โ โโ Column normalization โ โ
โ โ โ โโ Weight anomaly detection โ โ
โ โ โ โโ Unit value Z-scores โ โ
โ โ โ โโ Dwell time Z-scores โ โ
โ โ โ โโ Benford's Law deviation โ โ
โ โ โ โโ Route rarity scoring โ โ
โ โ โ โโ Temporal features โ โ
โ โ โ โโ Categorical encoding โ โ
โ โ โ โโ Log transformations โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ model_artifacts.joblib โ โ
โ โ โ (Persisted model + stats) โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Data Flow:
- User uploads CSV via React frontend
- Axios sends multipart form data to FastAPI backend
- Backend preprocesses data โ engineers features โ runs ML pipeline
- Results (risk scores + SHAP explanations) returned as JSON
- React renders interactive dashboard with charts and expandable rows
| Technology | Version | Purpose |
|---|---|---|
| Python | 3.11 | Runtime |
| FastAPI | 0.111.0 | REST API framework with automatic OpenAPI docs |
| XGBoost | 2.0.3 | Gradient boosted trees for classification |
| scikit-learn | 1.4.2 | Train/test split, metrics, Isolation Forest |
| SHAP | 0.45.0 | TreeExplainer for model interpretability |
| imbalanced-learn | 0.12.2 | SMOTE oversampling for class imbalance |
| pandas | 2.2.2 | Data manipulation and CSV/Excel parsing |
| NumPy | 1.26.4 | Numerical computation |
| SciPy | 1.13.0 | Statistical functions |
| joblib | 1.4.2 | Model artifact serialization |
| uvicorn | 0.29.0 | ASGI server with hot-reload |
| python-multipart | 0.0.9 | File upload parsing |
| Technology | Version | Purpose |
|---|---|---|
| React | 18.2.0 | UI framework |
| Recharts | 2.12.7 | Charts (Pie, Bar, Radar) |
| react-dropzone | 14.2.3 | Drag-and-drop file upload |
| Axios | 1.7.2 | HTTP client with FormData support |
| Lucide React | 0.395.0 | Icon library |
| clsx | 2.1.1 | Conditional CSS class utility |
| Technology | Purpose |
|---|---|
| Docker | Containerization |
| Docker Compose | Multi-service orchestration |
| Node 20 Alpine | Frontend container base |
| Python 3.11 Slim | Backend container base |
| Token | Value | Purpose |
|---|---|---|
--sans |
Inter, Geist Sans | Body typography |
--mono |
JetBrains Mono, Fira Code | Data & code typography |
--accent |
#3df8ab |
Primary accent (green) |
--red |
#ff5f5f |
Critical/danger |
--amber |
#fbbf24 |
Warning/medium risk |
--bg |
#09090b |
Base background (dark) |
- Docker & Docker Compose (recommended) โ OR:
- Python 3.11+ and Node.js 18+ (for local development)
# 1. Clone the repository
git clone https://github.com/Anik2812/SCRE.git
cd SCRE/smartcontainer
# 2. Build and launch both services
docker-compose up --build
# 3. Open in browser
# Frontend: http://localhost:3000
# Backend: http://localhost:8000
# API Docs: http://localhost:8000/docs (auto-generated Swagger UI)Note: First build may take 3โ5 minutes to install Python ML dependencies. Subsequent starts are near-instant thanks to Docker layer caching.
To run in the background:
docker-compose up --build -dTo stop:
docker-compose downTo stop and remove volumes (clears saved model):
docker-compose down -v# Navigate to the backend directory
cd smartcontainer/backend
# (Recommended) Create a virtual environment
python -m venv venv
# Activate the virtual environment
# On Windows:
venv\Scripts\activate
# On macOS/Linux:
source venv/bin/activate
# Install Python dependencies
pip install -r requirements.txt
# Start the FastAPI server with hot-reload
uvicorn main:app --reload --port 8000The backend will be accessible at http://localhost:8000.
Interactive API documentation is auto-generated at http://localhost:8000/docs.
# Navigate to the frontend directory
cd smartcontainer/frontend
# Install Node.js dependencies
npm install
# Start the React development server
npm startThe frontend will open at http://localhost:3000.
Proxy Configuration: The React dev server automatically proxies
/api/*requests to the backend. In Docker, this uses the internal service namesmartcontainer-api:8000. In local development, updateproxyinpackage.jsontohttp://localhost:8000if needed.
- The React app shows "API Online" with a green pulse indicator in the sidebar
- Navigate to
http://localhost:8000/api/healthโ should return:{"status": "ok", "service": "SmartContainer Risk Engine"}
smartcontainer/
โโโ docker-compose.yml # Multi-service orchestration
โ
โโโ backend/
โ โโโ Dockerfile # Python 3.11-slim container
โ โโโ requirements.txt # Pinned Python dependencies
โ โโโ main.py # FastAPI app โ 5 REST endpoints
โ โโโ model.py # ML pipeline โ training, prediction, SHAP
โ โโโ features.py # Feature engineering engine (24 features)
โ โโโ model_artifacts.joblib # Persisted model, explainer, and fit stats
โ โโโ model_store/ # Docker volume mount for model persistence
โ
โโโ frontend/
โ โโโ Dockerfile # Node 20-alpine container
โ โโโ package.json # React dependencies and proxy config
โ โโโ public/
โ โ โโโ index.html # HTML entry point
โ โโโ src/
โ โโโ index.js # React DOM render entry
โ โโโ index.css # Design system โ CSS variables, animations
โ โโโ App.jsx # Main app shell โ sidebar, tabs, routing
โ โโโ api.js # Axios HTTP client โ 5 API functions
โ โโโ components/
โ โโโ TrainPanel.jsx # Model training โ upload, progress, results
โ โโโ PredictPanel.jsx # Risk scoring โ upload, summary, preview
โ โโโ MetricsPanel.jsx # Model accuracy โ confusion matrix, radar
โ โโโ Dashboard.jsx # Full dashboard โ charts, table, export
โ
โโโ README.md # This file
| File | Lines | Description |
|---|---|---|
main.py |
103 | FastAPI application with CORS middleware, file upload parsing (CSV/Excel), and 5 REST endpoints for health check, training, prediction, metrics retrieval, and scored CSV download |
model.py |
338 | Complete ML pipeline โ label normalization, stratified splitting, reputation scoring, Isolation Forest fitting, SMOTE oversampling, XGBoost training with early stopping, 5-fold cross-validation, precision-recall threshold optimization, SHAP explanation generation, and artifact persistence via joblib |
features.py |
259 | Feature engineering engine โ column normalization, Benford's Law deviation scoring, weight ratio/diff/flag computation, unit value Z-scores per HS code, dwell time Z-scores per port, temporal features (night/weekend/combined), route rarity, categorical encoding, log transformations, and value-to-weight ratios. Supports both training mode (fits all stats) and inference mode (applies pre-fitted stats โ zero leakage) |
| File | Lines | Description |
|---|---|---|
App.jsx |
231 | Main application shell with dark-themed sidebar navigation, 4-step workflow (Train โ Score โ Accuracy โ Dashboard), API health polling, live clock, metric badges, and panel routing with step locking |
api.js |
10 | Axios HTTP client providing 5 exported functions: healthCheck, getMetrics, trainModel, predictRisk, downloadCSV โ all using the proxy-based relative URL pattern |
TrainPanel.jsx |
238 | Drag-and-drop CSV upload for training with progress animation, inline result display (Macro F1, Critical Recall, Critical Precision, AUC, threshold), mini confusion matrix visualization, and tooltip-enhanced metric bars |
PredictPanel.jsx |
219 | Drag-and-drop CSV upload for scoring with summary statistics (total containers, critical count, avg score), top-100 flagged container preview with color-coded score bars, expandable row details, and CSV download functionality |
MetricsPanel.jsx |
219 | Comprehensive model evaluation panel with individual metric bars (F1, Recall, Precision, AUC), letter-grade auto-assignment, interactive Recharts radar chart, full confusion matrix breakdown, and downloadable plain-text report |
Dashboard.jsx |
274 | Full risk analysis dashboard with Recharts PieChart (risk distribution), BarChart (score histogram), sortable/filterable data table with column-wise sorting, search, risk-level filter, expandable container details, and color-coded level badges |
The application follows a guided 4-step workflow:
- Navigate to the Train Model tab (Step 1)
- Drag-and-drop (or click to browse) your labeled CSV file
- The CSV must contain a label column:
Clearance_Status,Risk_Level, orLabel - Label mapping:
- Critical:
Critical,High Risk,High,1,True,Flag - Low Risk:
Clear,Low Risk,Low, or any other value
- Critical:
- Wait for training to complete (~10โ30 seconds depending on dataset size)
- Review training results:
- Macro F1 Score โ balanced accuracy across both classes
- Critical Recall โ percentage of actual Critical containers correctly identified
- Critical Precision โ percentage of flagged containers that are actually Critical
- AUC โ area under the ROC curve
- Optimal Threshold โ auto-tuned classification cutoff
- Confusion Matrix โ visual TP/FP/TN/FN breakdown
Minimum Requirement: At least 10 Critical samples are needed for reliable training. The system will reject datasets with fewer.
- Navigate to the Score Cargo tab (Step 2)
- Upload any container CSV (labeled or unlabeled)
- View the risk scoring summary:
- Total containers processed
- Number flagged as Critical
- Average risk score
- Critical percentage
- Review the top-100 highest-risk containers with:
- Risk Score (0โ100 scale)
- Risk Level badge (Critical / Low Risk)
- Plain-English explanation of why each container was flagged
- Download the full scored dataset as CSV
- Navigate to the Accuracy tab (Step 3) โ unlocks after training
- View detailed model performance metrics:
- Individual metric bars with letter grades (A+ through D)
- Interactive radar chart comparing all metrics at a glance
- Full confusion matrix with counts and percentages
- Download a plain-text accuracy report
- Navigate to the Dashboard tab (Step 4) โ unlocks after scoring
- Explore the full risk analysis:
- Pie chart showing Critical vs Low Risk distribution
- Bar histogram showing the risk score distribution
- Interactive data table with:
- Column-wise sorting (click any header)
- Search by Container ID
- Filter by risk level
- Expandable rows for full container details
- Color-coded risk score bars and level badges
Container_ID,Declaration_Date,Declaration_Time,Trade_Regime,Origin_Country,
Destination_Port,Destination_Country,HS_Code,Importer_ID,Exporter_ID,
Declared_Value,Declared_Weight,Measured_Weight,Shipping_Line,
Dwell_Time_Hours,Clearance_Status| Column | Type | Description | Example |
|---|---|---|---|
Container_ID |
String | Unique identifier for the container | CONT-2024-00153 |
Declaration_Date |
Date | Date of customs declaration | 2024-06-15 |
Declaration_Time |
Time | Time of declaration (HH:MM:SS) | 14:30:00 |
Trade_Regime |
String | Import / Export / Transit | Import |
Origin_Country |
String | ISO country code of origin | CN |
Destination_Port |
String | Port identifier | PORT_MOMBASA |
Destination_Country |
String | ISO country code of destination | KE |
HS_Code |
String | Harmonized System commodity code | 854231 |
Importer_ID |
String | Registered importer identifier | IMP_0042 |
Exporter_ID |
String | Registered exporter identifier | EXP_0087 |
Declared_Value |
Numeric | Total declared value (USD) | 45000.00 |
Declared_Weight |
Numeric | Weight declared on paperwork (kg) | 12000 |
Measured_Weight |
Numeric | Actual measured weight (kg) | 12850 |
Shipping_Line |
String | Carrier/shipping line | MAERSK |
Dwell_Time_Hours |
Numeric | Hours the container waited at port | 72 |
Clearance_Status |
String | Label column (for training only) | Critical |
The label column can be named Clearance_Status, Risk_Level, Label, or Status. Accepted values:
| Maps to Critical | Maps to Low Risk |
|---|---|
Critical |
Clear |
High Risk |
Low Risk |
High |
Low |
1 |
0 |
True |
False |
Flag |
Any other value |
Flexible Columns: Missing columns are automatically filled with safe defaults. The system gracefully handles partial data, but more complete data yields better predictions.
Raw CSV
โ
โผ
Label Normalization
โ Maps varied label strings to binary (Critical=1, Low Risk=0)
โ
โผ
Stratified Train/Test Split (80/20)
โ Preserves class ratios in both sets
โ
โผ
Reputation Scoring (Training Set Only)
โ Computes per-importer and per-exporter historical violation rates
โ
โผ
Feature Engineering (Training Set Only)
โ 24 features: weight anomalies, Z-scores, Benford, route rarity,
โ temporal patterns, categorical encodings, log transforms
โ
โผ
Isolation Forest (Fitted on Training Set)
โ 300 estimators, 6% contamination โ Anomaly_Score feature
โ
โผ
SMOTE Oversampling (Training Set Only)
โ Synthetic minority oversampling to balance classes
โ
โผ
XGBoost Training
โ 600 trees, depth=5, lr=0.04, early stopping (40 rounds)
โ Eval metric: Area Under Precision-Recall Curve (AUCPR)
โ scale_pos_weight for additional class balancing
โ
โผ
5-Fold Stratified Cross-Validation
โ Honest metric estimate on training set
โ
โผ
Threshold Optimization
โ Sweeps precision-recall curve to maximize recall
โ subject to precision โฅ 72%, floor at 40% probability
โ
โผ
Test Set Evaluation
โ Final metrics: Macro F1, Critical Recall, Precision, AUC
โ Confusion matrix generation
โ
โผ
SHAP TreeExplainer Initialization
โ
โผ
Artifact Persistence (joblib)
โโ Saves: XGBoost model, SHAP explainer, fit_stats, feature_cols, metrics
| Parameter | Value | Rationale |
|---|---|---|
n_estimators |
600 | High budget, controlled by early stopping |
max_depth |
5 | Moderate complexity โ prevents overfitting |
learning_rate |
0.04 | Low rate for fine-grained gradient descent |
subsample |
0.8 | Row subsampling for regularization |
colsample_bytree |
0.75 | Feature subsampling per tree |
min_child_weight |
3 | Minimum samples per leaf |
gamma |
0.1 | Minimum loss reduction for split |
reg_alpha (L1) |
0.1 | Sparse regularization |
reg_lambda (L2) |
1.0 | Ridge regularization |
scale_pos_weight |
Auto | Calculated as n_negative / n_positive |
eval_metric |
aucpr |
Area under precision-recall curve โ optimal for imbalanced data |
early_stopping_rounds |
40 | Stops training when test AUCPR stops improving |
Raw CSV
โ
โผ
Load Persisted Artifacts
โ XGBoost model, SHAP explainer, fit_stats, threshold
โ
โผ
Feature Engineering (Inference Mode)
โ Applies pre-fitted stats from training โ zero leakage
โ
โผ
Reputation Scoring (Pre-fitted)
โ Maps importer/exporter IDs to training-set risk scores
โ
โผ
Isolation Forest Anomaly Scoring (Pre-fitted)
โ
โผ
XGBoost Probability Prediction
โ
โผ
Threshold Application (Optimized)
โ Classifies: probability โฅ threshold โ Critical
โ
โผ
SHAP Value Computation
โ Per-container feature importance values
โ
โผ
Plain-English Explanation Generation
โ Top-3 most influential features โ human-readable sentences
โ
โผ
Result DataFrame
โโ Original columns + Risk_Score (0-100) + Risk_Level + Explanation_Summary + Anomaly_Score
The feature engine (features.py) produces 24 numeric features from raw shipment data, with strict separation between training-mode (fits statistics) and inference-mode (applies pre-fitted statistics).
| Feature | Formula | Description |
|---|---|---|
Weight_Ratio |
Measured / Declared weight | Direct ratio โ values far from 1.0 indicate discrepancies |
Weight_Diff_Pct |
|Measured โ Declared| / Declared | Percentage weight deviation |
Weight_Flag |
1 if ratio < 0.95 or > 1.05 | Binary flag for >5% weight discrepancy |
| Feature | Formula | Description |
|---|---|---|
Unit_Value_Zscore |
(Unit Value โ HS Mean) / HS Std | Z-score of $/kg compared to same HS code average โ detects under/over-valuation |
Value_Weight_Ratio |
Declared Value / Declared Weight | Raw value density โ unusual ratios flag misclassified goods |
Benford_Dev |
|digit_freq โ expected_freq| | Deviation from Benford's Law โ detects fabricated declared values |
Log_Declared_Value |
log(1 + Declared_Value) | Log-transformed value for scale normalization |
Log_Declared_Weight |
log(1 + Declared_Weight) | Log-transformed weight |
| Feature | Formula | Description |
|---|---|---|
Dwell_Zscore |
(Dwell โ Port Mean) / Port Std | Dwell time deviation vs port-specific average |
Log_Dwell_Time |
log(1 + Dwell_Time_Hours) | Log-transformed dwell time |
Route_Risk |
1 โ route_frequency | Trade route rarity โ uncommon OriginโPortโDestination combinations score higher |
| Feature | Formula | Description |
|---|---|---|
Hour |
Declaration hour (0โ23) | Raw declaration hour |
DayOfWeek |
Day of week (0=Mon, 6=Sun) | Day the declaration was filed |
Is_Night |
1 if hour โฅ 22 or โค 5 | Night-time declaration flag |
Is_Weekend |
1 if Saturday or Sunday | Weekend declaration flag |
Night_HighValue |
Is_Night AND value > Q75 | High-value night-time declaration โ suspicious pattern |
Weekend_Night |
Is_Weekend AND Is_Night | Weekend night declaration โ higher risk pattern |
| Feature | Formula | Description |
|---|---|---|
Importer_Risk |
Training-set violation rate | Historical % of importer's shipments that were Critical |
Exporter_Risk |
Training-set violation rate | Historical % of exporter's shipments that were Critical |
| Feature | Source | Description |
|---|---|---|
Trade_Regime_Enc |
Trade_Regime | Ordinal: Import=0, Export=1, Transit=2 |
Origin_Enc |
Origin_Country | Label-encoded country of origin |
Dest_Enc |
Destination_Country | Label-encoded destination country |
Port_Enc |
Destination_Port | Label-encoded port |
HS_Enc |
HS_Code | Label-encoded commodity code |
| Feature | Source | Description |
|---|---|---|
Anomaly_Score |
Isolation Forest | Outlier score across all base features โ higher = more anomalous |
Every prediction includes a plain-English explanation generated from SHAP values. The system identifies the top-3 most influential features for each container and translates them into human-readable sentences.
| Explanation | Triggered When |
|---|---|
| "Weight discrepancy 12.5%" | Weight_Diff_Pct is high |
| "Significant weight anomaly (>5% gap)" | Weight_Flag = 1 |
| "Declared value undervalued for this commodity (โ2.3ฯ from average)" | Unit_Value_Zscore is significantly negative |
| "Unusual dwell time at port (3.1ฯ from average)" | Dwell_Zscore is high |
| "High-value shipment declared at night" | Night_HighValue = 1 |
| "Declaration made outside business hours" | Is_Night = 1 |
| "Importer has prior violation history (23% rate)" | Importer_Risk > 0.15 |
| "Declared value digits deviate from expected pattern" | Benford_Dev > 0.05 |
| "Uncommon trade route (rarity score 0.87)" | Route_Risk > 0.5 |
| "Statistical outlier across multiple features" | Anomaly_Score > 0.5 |
If no dominant risk factors are detected, the explanation reads: "No dominant risk factors detected".
- Local:
http://localhost:8000 - Docker:
http://localhost:8000(mapped from container port)
Health check endpoint for monitoring and readiness probes.
Response:
{
"status": "ok",
"service": "SmartContainer Risk Engine"
}Upload a labeled CSV/Excel file to train the ML model.
Request:
- Content-Type:
multipart/form-data - Body:
fileโ CSV or Excel file with label column
Response (Success):
{
"success": true,
"message": "Model trained on 2400 samples",
"metrics": {
"macro_f1": 0.8923,
"cv_macro_f1": 0.8645,
"critical_recall": 0.9167,
"critical_precision": 0.7857,
"auc": 0.9512,
"threshold": 0.4235,
"confusion_matrix": [[450, 12], [10, 128]],
"train_size": 2400,
"test_size": 150,
"critical_ratio": 0.2133,
"n_features": 25,
"best_iteration": 287
}
}Error Responses:
| Code | Condition |
|---|---|
| 400 | Empty file, missing label column, or fewer than 10 Critical samples |
| 500 | Internal training error |
Upload a CSV/Excel file to score containers against the trained model.
Request:
- Content-Type:
multipart/form-data - Body:
fileโ CSV or Excel file (labeled or unlabeled)
Response (Success):
{
"success": true,
"summary": {
"total": 500,
"critical": 47,
"low_risk": 453,
"avg_score": 23.4,
"critical_pct": 9.4
},
"containers": [
{
"Container_ID": "CONT-2024-00153",
"Risk_Score": 94.7,
"Risk_Level": "Critical",
"Explanation_Summary": "Weight discrepancy 12.5%. Declared value undervalued for this commodity (โ2.3ฯ from average). Importer has prior violation history (23% rate)",
"Anomaly_Score": 0.7823,
"Origin_Country": "CN",
"Destination_Country": "KE",
"Declared_Value": 12000,
"Declared_Weight": 5000,
"Measured_Weight": 5625
}
]
}Error Responses:
| Code | Condition |
|---|---|
| 400 | Model not trained yet, or empty file |
| 500 | Internal prediction error |
Retrieve the evaluation metrics from the most recently trained model.
Response:
{
"macro_f1": 0.8923,
"cv_macro_f1": 0.8645,
"critical_recall": 0.9167,
"critical_precision": 0.7857,
"auc": 0.9512,
"threshold": 0.4235,
"confusion_matrix": [[450, 12], [10, 128]],
"train_size": 2400,
"test_size": 150,
"critical_ratio": 0.2133,
"n_features": 25,
"best_iteration": 287
}Error Responses:
| Code | Condition |
|---|---|
| 404 | No trained model found |
Upload a CSV/Excel file and receive a scored CSV file as a download.
Request:
- Content-Type:
multipart/form-data - Body:
fileโ CSV or Excel file
Response:
- Content-Type:
text/csv - Content-Disposition:
attachment; filename=risk_predictions.csv - Body: CSV with columns
Container_ID,Risk_Score,Risk_Level,Explanation_Summary
Error Responses:
| Code | Condition |
|---|---|
| 500 | Model not trained, or internal error |
The main application provides:
- Sidebar navigation with numbered steps (1โ4) and lock icons for unavailable tabs
- API status indicator โ green pulsing dot when connected, red when disconnected
- Top bar โ shows current step number, active model metrics (F1 + Recall), and current date
- Bottom tab strip โ quick navigation between all steps
- Smart tab locking โ Accuracy and Dashboard tabs are locked until prerequisites are met
- Live clock โ updates every second in the sidebar footer
- Drag-and-drop zone with react-dropzone
- File validation and size display
- Animated training progress
- Post-training result display with:
- Metric bars (F1, Recall, Precision, AUC) with percentage fills
- Mini confusion matrix with color-coded cells (TP/TN/FP/FN)
- Tooltips explaining each metric
- Threshold and training metadata
- Drag-and-drop upload for scoring
- Summary cards showing total, critical count, average score, critical percentage
- Top-100 flagged containers table with:
- Visual risk score bars (green < 40 < amber < 70 < red)
- Risk level badges
- Expandable rows showing full container details + explanation
- CSV download button for full scored results
- Individual metric bars with auto-calculated letter grades:
- A+ (โฅ 90%), A (โฅ 85%), B (โฅ 78%), C (โฅ 68%), D (< 68%)
- Interactive Recharts Radar Chart for at-a-glance metric comparison
- Detailed confusion matrix with percentage breakdown
- Downloadable plain-text accuracy report
- PieChart โ Critical vs Low Risk distribution with labels
- BarChart โ Risk score histogram (10-point buckets)
- Data table with full interactivity:
- Click column headers to sort (ascending/descending toggle)
- Search by Container ID
- Filter by risk level (All / Critical / Low Risk)
- Click any row to expand full details
- Color-coded score bars and level badges
| Variable | Service | Default | Description |
|---|---|---|---|
PYTHONUNBUFFERED |
Backend | 1 |
Ensures Python prints appear in Docker logs |
REACT_APP_API_URL |
Frontend | http://localhost:8000 |
Backend URL for API calls |
CHOKIDAR_USEPOLLING |
Frontend | true |
Enables file watching in Docker for hot-reload |
WDS_SOCKET_PORT |
Frontend | 0 |
Fixes WebSocket port for dev server in Docker |
| Volume | Mount Point | Purpose |
|---|---|---|
model_data |
/app/model_store |
Persists trained model between container restarts |
./backend |
/app |
Live code sync for backend development |
The frontend package.json includes a proxy configuration:
{
"proxy": "http://smartcontainer-api:8000"
}This routes all /api/* requests from the React dev server to the backend. In Docker Compose, smartcontainer-api resolves to the backend container. For local development without Docker, change this to http://localhost:8000.
| Issue | Solution |
|---|---|
| "API Offline โ start Docker" | Start the backend: docker-compose up or uvicorn main:app --reload --port 8000 |
| "Model not trained yet" | Upload a labeled CSV in Step 1 (Train Model) before scoring |
| "Only N Critical samples found" | Your training data needs at least 10 Critical-labeled rows |
| "No label column found" | Ensure your CSV has a column named Clearance_Status, Risk_Level, Label, or Status |
| CORS errors in browser | The backend allows all origins by default. Check that both services are running |
| Frontend shows blank page | Check browser console for errors. Ensure npm install was run |
| Docker build fails | Run docker-compose build --no-cache to rebuild from scratch |
| Slow first training | Expected โ XGBoost + SHAP computation takes 10โ30s. Subsequent predictions are faster |
| Port 3000/8000 already in use | Stop other services, or modify port mappings in docker-compose.yml |
- More data = better model โ aim for 500+ rows for reliable results
- Label balance matters โ if < 5% are Critical, the model may underperform; SMOTE helps but can't fully compensate for extreme imbalance
- Complete data is ideal โ missing columns are auto-filled with defaults, but actual values give the model more signal
- Consistent IDs โ reusing the same
Importer_IDandExporter_IDacross rows enables reputation scoring
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m "Add my feature" - Push to the branch:
git push origin feature/my-feature - Open a Pull Request
- Backend auto-reloads on file changes (uvicorn
--reload) - Frontend auto-reloads via React dev server HMR
- API docs are always available at
http://localhost:8000/docs - The model artifact (
model_artifacts.joblib) is gitignored by default
This project was developed as part of the HackMined hackathon. See the repository for license details.
Built with โค๏ธ using XGBoost, FastAPI, React, and SHAP