Skip to content
12advanced

Complete ML Pipeline

A regression workflow from start to finish on the Housing-Mini dataset: load, explore, split, scale, fit a Ridge model, evaluate and plot.

What you will learn

  • Use deepbox/datasets for loadHousingMini.
  • Use deepbox/ml for Ridge.
  • Use deepbox/metrics for r2Score, mse, mae.
  • Use deepbox/preprocess for trainTestSplit, StandardScaler.
  • A regression workflow from start to finish on the Housing-Mini dataset: load, explore, split, scale, fit a Ridge model, evaluate and plot.

Source

index.ts
/** * Example 12: Complete ML Pipeline * * A regression workflow from start to finish on the Housing-Mini dataset: * load, explore, split, scale, fit a Ridge model, evaluate and plot. */ import { mkdirSync, writeFileSync } from "node:fs";import { loadHousingMini } from "deepbox/datasets";import { mae, mse, r2Score } from "deepbox/metrics";import { Ridge } from "deepbox/ml";import { tensor } from "deepbox/ndarray";import { Figure } from "deepbox/plot";import { StandardScaler, trainTestSplit } from "deepbox/preprocess";import { mean, std } from "deepbox/stats"; console.log("=".repeat(60));console.log("Example 12: Complete Machine Learning Pipeline");console.log("=".repeat(60)); mkdirSync("docs/examples/12-complete-pipeline/output", { recursive: true }); // Step 1: Load dataconsole.log("\nStep 1: Loading the dataset");console.log("-".repeat(60)); const dataset = loadHousingMini();console.log("Loaded the Housing-Mini dataset");console.log(`  Samples: ${dataset.data.shape[0]}`);console.log(`  Features: ${dataset.data.shape[1]}`); // Step 2: Exploratory data analysisconsole.log("\nStep 2: Exploratory data analysis");console.log("-".repeat(60)); // Take the first feature column. slice({}, 0) keeps every row of axis 0// and selects index 0 on axis 1.const feature = dataset.data.slice({}, 0); console.log("Feature 1 statistics:");console.log(`  Mean: ${Number(mean(feature).item()).toFixed(2)}`);console.log(`  Std:  ${Number(std(feature).item()).toFixed(2)}`); // Step 3: Data preprocessingconsole.log("\nStep 3: Data preprocessing");console.log("-".repeat(60)); const [XTrain, XTest, yTrain, yTest] = trainTestSplit(dataset.data, dataset.target, {  testSize: 0.2,  randomState: 42,  shuffle: true,}); console.log("Split the data:");console.log(`  Training: ${XTrain.shape[0]} samples`);console.log(`  Testing:  ${XTest.shape[0]} samples`); // Fit the scaler on the training rows only, so no test information leaks in.const scaler = new StandardScaler();scaler.fit(XTrain);const XTrainScaled = scaler.transform(XTrain);const XTestScaled = scaler.transform(XTest); console.log("Scaled the features with StandardScaler"); // Step 4: Model trainingconsole.log("\nStep 4: Model training");console.log("-".repeat(60)); const model = new Ridge({ alpha: 1.0 });model.fit(XTrainScaled, yTrain); console.log("Trained Ridge regression (alpha = 1.0)"); // Step 5: Model evaluationconsole.log("\nStep 5: Model evaluation");console.log("-".repeat(60)); const yPred = model.predict(XTestScaled); const r2 = r2Score(yTest, yPred);const mseVal = mse(yTest, yPred);const maeVal = mae(yTest, yPred); console.log("Performance metrics:");console.log(`  R² Score: ${r2.toFixed(4)}`);console.log(`  MSE:      ${mseVal.toFixed(4)}`);console.log(`  MAE:      ${maeVal.toFixed(4)}`); // Step 6: Visualizationconsole.log("\nStep 6: Results visualization");console.log("-".repeat(60)); // Predictions vs actual values. Tensors go straight into the plot.const fig = new Figure({ width: 640, height: 480 });const ax = fig.addAxes(); ax.scatter(yTest, yPred, {  color: "#1f77b4",  size: 8,}); // The red line marks perfect predictions (predicted equals actual).const lo = Math.min(Number(yTest.min().item()), Number(yPred.min().item()));const hi = Math.max(Number(yTest.max().item()), Number(yPred.max().item()));ax.plot(tensor([lo, hi]), tensor([lo, hi]), {  color: "#ff0000",  linewidth: 2,});ax.setTitle("Predictions vs Actual Values");ax.setXLabel("Actual");ax.setYLabel("Predicted"); const svg = fig.renderSVG();writeFileSync("docs/examples/12-complete-pipeline/output/predictions.svg", svg.svg);console.log("Saved: output/predictions.svg"); // Step 7: Summaryconsole.log("\nStep 7: Pipeline summary");console.log("-".repeat(60)); console.log("Steps run:");console.log("  1. Load data (Housing-Mini)");console.log("  2. Exploratory analysis");console.log("  3. Train/test split (80/20)");console.log("  4. Feature scaling (StandardScaler)");console.log("  5. Model training (Ridge)");console.log(`  6. Model evaluation (R² = ${r2.toFixed(3)})`);console.log("  7. Results visualization"); console.log("\nNotes:");console.log("  Split first, then fit the scaler on the training set, to avoid data leakage.");console.log("  Report more than one metric: R² shows fit quality, MAE is in the target's units."); console.log(`\n${"=".repeat(60)}`);console.log("Pipeline finished");console.log("=".repeat(60));

Output

Console output
One SVG file is written to `output/`: `predictions.svg`, a scatter plot of predicted against actual values.