// ML Studio — Predictive, Prescriptive, Time-Series, AutoML, Explainable AI. const ML_MODELS = [ { name: "Demand Forecast — GeM SKUs", algo: "Prophet + LGBM", target: "units_next_qtr", acc: 94.2, status: "Production", trained: "2h ago", drift: "ok" }, { name: "Vendor Fraud Detection", algo: "XGBoost", target: "is_fraud", acc: 97.8, status: "Production", trained: "1d ago", drift: "ok" }, { name: "Tender Volume Forecast", algo: "LSTM", target: "tenders_90d", acc: 91.4, status: "Production", trained: "6h ago", drift: "warn" }, { name: "Transformer Failure Predict", algo: "Random Forest", target: "fail_24h", acc: 96.1, status: "Production", trained: "3h ago", drift: "ok" }, { name: "Scheme Uptake — Churn", algo: "LightGBM", target: "will_lapse", acc: 88.6, status: "Staging", trained: "12h ago", drift: "warn" }, { name: "Revenue Forecast (state)", algo: "Prophet", target: "rev_next_month", acc: 92.9, status: "Production", trained: "4h ago", drift: "ok" }, { name: "Crop Yield Estimator", algo: "Ensemble + CNN", target: "yield_qtl_ha", acc: 89.3, status: "Staging", trained: "1d ago", drift: "ok" }, ]; const ML_FEATURES = [ { f: "Festival index", w: 0.28 }, { f: "GST filings", w: 0.19 }, { f: "Prev 90d demand", w: 0.15 }, { f: "Rainfall dev.", w: 0.12 }, { f: "Vendor lead time", w: 0.10 }, { f: "Price index", w: 0.09 }, { f: "Holiday count", w: 0.07 }, ]; const AUTOML = [ { model: "LightGBM", metric: "RMSE 41.2", score: 94.2, best: true }, { model: "XGBoost", metric: "RMSE 44.8", score: 92.6 }, { model: "Prophet", metric: "RMSE 48.1", score: 91.0 }, { model: "ElasticNet", metric: "RMSE 61.4", score: 84.2 }, { model: "ARIMA", metric: "RMSE 68.9", score: 80.1 }, ]; function ForecastChart({ history, forecast, upper, lower, labels, w = 620, h = 250 }) { const pad = { t: 14, r: 14, b: 26, l: 44 }; const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b; const all = [...history, ...forecast, ...upper, ...lower]; const min = Math.min(...all) * 0.94, max = Math.max(...all) * 1.02; const range = max - min || 1; const n = history.length + forecast.length; const xStep = iw / (n - 1); const X = (i) => pad.l + i * xStep; const Y = (v) => pad.t + ih - ((v - min) / range) * ih; const histPts = history.map((v, i) => [X(i), Y(v)]); const hIdx = history.length - 1; const fcPts = forecast.map((v, i) => [X(hIdx + i), Y(v)]); const upPts = [[X(hIdx), Y(history[hIdx])], ...upper.map((v, i) => [X(hIdx + 1 + i), Y(v)])]; const loPts = [[X(hIdx), Y(history[hIdx])], ...lower.map((v, i) => [X(hIdx + 1 + i), Y(v)])]; const bandD = [...upPts.map((p, i) => `${i ? 'L' : 'M'} ${p[0].toFixed(1)} ${p[1].toFixed(1)}`), ...loPts.slice().reverse().map(p => `L ${p[0].toFixed(1)} ${p[1].toFixed(1)}`), 'Z'].join(' '); const line = (pts) => pts.map((p, i) => `${i ? 'L' : 'M'} ${p[0].toFixed(1)} ${p[1].toFixed(1)}`).join(' '); return ( {Array.from({ length: 5 }).map((_, i) => { const y = pad.t + (ih / 4) * i; return ; })} {Array.from({ length: 5 }).map((_, i) => { const y = pad.t + (ih / 4) * i; const v = max - (range / 4) * i; return {Math.round(v)}; })} {labels.map((l, i) => (i % 3 === 0 || i === n - 1) ? {l} : null)} now {fcPts.map((p, i) => )} ); } function WhatIf() { const [mkt, setMkt] = useState(40); const [price, setPrice] = useState(0); const [festival, setFestival] = useState(60); const base = 1290; const predicted = Math.round(base * (1 + (mkt - 40) / 220) * (1 - price / 140) * (1 + (festival - 60) / 260)); const delta = ((predicted - base) / base) * 100; const rows = [ { label: "Marketing spend", val: mkt, set: setMkt, min: 0, max: 100, unit: "₹ index" }, { label: "Price change", val: price, set: setPrice, min: -20, max: 20, unit: "%" }, { label: "Festival intensity", val: festival, set: setFestival, min: 0, max: 100, unit: "index" }, ]; return (

What-if Simulation

Prescriptive · scenario planning
Live
{rows.map((r, i) => (
{r.label} {r.val > 0 && r.unit === '%' ? '+' : ''}{r.val} {r.unit}
r.set(Number(e.target.value))} style={{ width: '100%', accentColor: 'var(--primary)' }}/>
))}
Predicted demand — next quarter
{fmtNum(predicted * 1000)}
= 0 ? 'var(--ok)' : 'var(--danger)', fontWeight: 600, display: 'flex', alignItems: 'center', gap: 4 }}> = 0 ? 'trending' : 'trendingDown'} size={13}/>{fmtPct(delta)} vs baseline · units
); } function MLStudioScreen() { const months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","Jan","Feb","Mar","Apr","May","Jun"]; const history = [820,845,910,880,940,1010,1060,1040,1120,1180,1210,1290]; const forecast = [1330,1370,1420,1460,1500,1560]; const upper = [1370,1440,1520,1600,1680,1780]; const lower = [1300,1310,1330,1350,1360,1380]; return (
ML Studio & Forecasting
24 models · 19 in production · AutoML + Explainable AI · MLflow registry · Predictive & prescriptive
Models in production
19/24
+3 this month
Avg accuracy
94.2%
+1.4% vs baseline
Predictions today
2.4M
GPU · 42ms p95
Drift alerts
3
2 models need retrain

Demand Forecast — GeM SKUs

Prophet + LightGBM · 6-month horizon · 92% confidence band
Actual Forecast

Model Registry

MLflow · versioned · auto-monitored for drift
{ML_MODELS.map((m, i) => ( ))}
ModelAlgorithmAccuracyStatusTrained
{m.name}
{m.target}
{m.algo}
= 95 ? 'var(--ok)' : m.acc >= 90 ? 'var(--primary)' : 'var(--accent)' }}/>
{m.acc}%
{m.status} {m.trained}

Feature Importance

SHAP · Demand Forecast
XAI
f.w)} labels={ML_FEATURES.map(f => f.f)} horizontal w={300} h={170} format={v => v.toFixed(2)} color="var(--primary)" accent="var(--accent)"/>

AutoML Leaderboard

42 candidates · 5-fold CV
{AUTOML.map((a, i) => (
{i + 1}
{a.model}{a.best && Best}
{a.metric}
{a.score}
))}
Prescriptive recommendations Optimizer
Increase safety stock 8% for medical & electronics SKUs before the festival window — forecast shows a ₹42 Cr demand surge in Oct–Nov.
Retrain "Tender Volume Forecast" — feature drift on bid_lead_time exceeds 0.15 PSI threshold.
Shift ₹6 Cr procurement from Q3 to Q2 to smooth the predicted supply bottleneck in Karnataka.
); } window.MLStudioScreen = MLStudioScreen;