// 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 ( ); } 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 (
| Model | Algorithm | Accuracy | Status | Trained |
|---|---|---|---|---|
|
{m.name}
{m.target}
|
{m.algo} |
= 95 ? 'var(--ok)' : m.acc >= 90 ? 'var(--primary)' : 'var(--accent)' }}/>
{m.acc}%
|
{m.status} | {m.trained} |