California Housing Regression

Introduction

Welcome to the final lesson of "Building and Applying Your Neural Network Library"! Congratulations on making it this far — you've accomplished something truly remarkable. Over the course of this path, you've built a complete, modular neural network library from scratch, learning the inner workings of layers, activations, optimizers, loss functions, and the orchestration that brings them all together. You've also mastered the essential data preparation techniques needed for real-world machine learning applications.

Today, we're going to experience the incredible satisfaction of seeing all your hard work come together. We'll use our custom-built neural network library to tackle a real regression problem: predicting California housing prices. You'll see how the modular architecture you've carefully constructed makes it surprisingly straightforward to define complex neural networks, train them efficiently, and evaluate their performance on real data.

This lesson represents the culmination of your journey — the moment when theory meets practice and your carefully crafted code proves its worth on a meaningful problem. Let's put your neural network library to the ultimate test!

Setting Up the Data

Let's start by importing our components and setting up the data preprocessing pipeline. Since you mastered data preparation in the previous lesson, we'll handle this efficiently and effortlessly using JavaScript tools.

We'll use the fs module to load the data, papaparse to parse CSV, and our own trainTestSplit and standardScaler functions for splitting and scaling.

To speed up training, we'll randomly select 1,000 samples from the dataset.

import * as math from 'mathjs';
import seedrandom from 'seedrandom';
import fs from 'fs';
import Papa from 'papaparse';
import { trainTestSplit, standardScaler } from './main.js'; // Adjust path as needed

// 1. Load the California Housing dataset from CSV
const csv = fs.readFileSync('data/california_housing.csv', 'utf8');
const parsed = Papa.parse(csv, {
    header: true,
    dynamicTyping: true,
    skipEmptyLines: true
});

// Extract feature names and target
const allColumns = Object.keys(parsed.data[0]);
const featureNames = allColumns.slice(0, -1);
const targetName = allColumns[allColumns.length - 1];

// --- SUBSAMPLE DATA FOR FASTER TRAINING ---
const SAMPLE_SIZE = 1000;
const totalRows = parsed.data.length;
const random = seedrandom('subsample'); // For reproducibility
const indices = Array.from({ length: totalRows }, (_, i) => i);
// Shuffle indices
for (let i = indices.length - 1; i > 0; i--) {
    const j = Math.floor(random() * (i + 1));
    [indices[i], indices[j]] = [indices[j], indices[i]];
}
const selectedIndices = indices.slice(0, SAMPLE_SIZE);

// Build X and y using only the selected indices
const X = [];
const y = [];
for (const idx of selectedIndices) {
    const row = parsed.data[idx];
    X.push(featureNames.map(f => row[f]));
    y.push([row[targetName]]);
}

// 2. Split data into training and testing sets
const { XTrain, XTest, yTrain, yTest } = trainTestSplit(X, y, 0.2, 42);

// 3. Apply feature scaling (Standardization)
const scalerX = standardScaler(XTrain);
const XTrainScaled = scalerX.data;
const XTestScaled = scalerX.transform(XTest);

const scalerY = standardScaler(yTrain);
const yTrainScaled = scalerY.data;
const yTestScaled = scalerY.transform(yTest);

const numFeatures = XTrainScaled[0].length; // Will be 8 for this dataset
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal