Logistic Regression Classification

Demo of logistic regression classifier implemented using numericjs

HTML

<script src="http://www.numericjs.com/lib/numeric-1.2.3.min.js"></script>
<body>
    <div id="toolbar">
        Lambda:
        <input id="lambda" type="text" value="0.0" size="10"/>
        Group:
        <select id="group">
            <option value="0">Blue</option>
            <option value="1">Orange</option>
        </select>
    </div>
    <div id="content">
        <canvas id="canvas"></canvas>
    </div>
</body>

CSS

#toolbar, #content {
    width: 400px;
    margin: 0;
    padding: 0;
    text-align: center;
}

body, input, select {
    font: bold 11px arial,sans-serif;
}

JavaScript

function expand(a, b) {
    /*
        Expand [a, b] into polynomial features
    */
    return [1, a, b, a * a, b * b, a * b];
}

function sigmoid(x) {
    /*
        Logistic sigmoid function
    */
    return 1.0 / (1.0 + Math.exp(-x));

};

function render(gfx, theta, X, y) {
    /*
        Render graph and theta boundaries
    */
    var thetaT = theta;
    gfx.scale(10);
    // Render background
    for (var i = 0; i < 40; i++) {
        for (var j = 0; j < 40; j++) {
            var a = j / 20 - 1;
            var b = i / 20 - 1;
            var x = expand(a, b);
            var value = sigmoid(numeric.dot(thetaT, x));
            gfx.stroke(255 * value, 100, 255 * (1 - value));
            gfx.point(j, i);
        }
    }
    gfx.scale(0.1);
    gfx.stroke(0);
    // Render points
    for (var i = 0; i < X.length; i++) {
        if (y[i] > 0.5) {
            gfx.fill(255, 100, 50);
        } else {
            gfx.fill(50, 100, 255);
        }
        gfx.ellipse((X[i][1] + 1) * 200, (X[i][2] + 1) * 200, 5, 5);
    }
}

window.onload = (function() {
    // Lambda input
    var lambda = document.getElementById('lambda').value;
    var lambdaInput = document.getElementById('lambda');
    lambdaInput.onchange = function() {
        lambda = parseFloat(lambdaInput.value);
    };

    // Group input
    var group = document.getElementById('group').value;
    var groupInput = document.getElementById('group');
    groupInput.onchange = function() {
        group = parseFloat(groupInput.value);
    };

    // X is feature matrix, y is group vector
    var X = [], y = [];

    // Cost function for regularized logistic regression
    var cost = function(theta) {
        var H = numeric.dot(X, theta).map(sigmoid);
        var J = numeric.dot(y, numeric.log(H));
        J += numeric.dot(numeric.sub(1, y), numeric.log(numeric.sub(1, H)));
        J = -J / X.length;
        J += lambda / 2 / X.length * numeric.sum(numeric.pow(theta.slice(1), 2));
        return J;
   ...