Skip to content

Instantly share code, notes, and snippets.

@simplymathematics
Last active June 6, 2025 13:59
Show Gist options
  • Save simplymathematics/d658396f68c2e4e282e7b9003e93c8f6 to your computer and use it in GitHub Desktop.
Save simplymathematics/d658396f68c2e4e282e7b9003e93c8f6 to your computer and use it in GitHub Desktop.
An example of building models in javascript and plotting them with plotly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Model Visualization</title>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<h2>Linear SVM Model</h2>
<div id="plot" style="width: 700px; height: 600px;"></div>
<script type="module">
import { SVM } from './svm.js';
import { plotDecisionBoundary } from './plot.js';
const X = [
[1, 2],
[2, 3],
[3, 3],
[2, 1],
[3, 2]
];
const y = [1, 1, 1, -1, -1];
const svm = new SVM();
svm.fit(X, y);
plotDecisionBoundary(X, y, svm, 'Linear SVM Decision Boundary');
</script>
</body>
</html>
// plot.js
export function plotDecisionBoundary(X, y, model, title = 'SVM Decision Boundary') {
const x0 = X.map(row => row[0]);
const x1 = X.map(row => row[1]);
const scatter = {
x: x0,
y: x1,
mode: 'markers',
type: 'scatter',
marker: {
color: y,
colorscale: [['0', 'blue'], ['1', 'red']],
cmin: -1,
cmax: 1,
size: 10
},
name: 'Data Points'
};
const xMin = Math.min(...x0) - 1;
const xMax = Math.max(...x0) + 1;
const yMin = Math.min(...x1) - 1;
const yMax = Math.max(...x1) + 1;
const resolution = 100;
const xVals = Array.from({ length: resolution }, (_, i) =>
xMin + (i / (resolution - 1)) * (xMax - xMin)
);
const yVals = Array.from({ length: resolution }, (_, i) =>
yMin + (i / (resolution - 1)) * (yMax - yMin)
);
const zVals = yVals.map(yVal =>
xVals.map(xVal => {
const x_point = [xVal, yVal];
return model.dotProduct(x_point, model.w) - model.b;
})
);
const contour = {
z: zVals,
x: xVals,
y: yVals,
type: 'contour',
colorscale: 'BuRd',
contours: {
showlines: true,
start: -1,
end: 1,
size: 1
},
opacity: 0.6,
name: 'Decision Boundary'
};
const layout = {
title: title,
xaxis: { title: 'Feature 1' },
yaxis: { title: 'Feature 2' },
showlegend: false
};
Plotly.newPlot('plot', [contour, scatter], layout);
}
// svm.js
export class SVM {
constructor(learningRate = 0.001, lambdaParam = 0.01, nIters = 1000) {
this.lr = learningRate;
this.lambdaParam = lambdaParam;
this.nIters = nIters;
this.w = null;
this.b = 0;
}
dotProduct(a, b) {
return a.reduce((sum, val, i) => sum + val * b[i], 0);
}
subtractArrays(a, b) {
return a.map((val, i) => val - b[i]);
}
multiplyArrayScalar(arr, scalar) {
return arr.map(val => val * scalar);
}
fit(X, y) {
const nSamples = X.length;
const nFeatures = X[0].length;
const y_ = y.map(val => val <= 0 ? -1 : 1);
this.w = Array(nFeatures).fill(0);
this.b = 0;
for (let i = 0; i < this.nIters; i++) {
for (let idx = 0; idx < nSamples; idx++) {
const x_i = X[idx];
const condition = y_[idx] * (this.dotProduct(x_i, this.w) - this.b) >= 1;
if (condition) {
const grad = this.multiplyArrayScalar(this.w, 2 * this.lambdaParam);
this.w = this.subtractArrays(this.w, this.multiplyArrayScalar(grad, this.lr));
} else {
const grad = this.subtractArrays(
this.multiplyArrayScalar(this.w, 2 * this.lambdaParam),
this.multiplyArrayScalar(x_i, y_[idx])
);
this.w = this.subtractArrays(this.w, this.multiplyArrayScalar(grad, this.lr));
this.b -= this.lr * y_[idx];
}
}
}
}
predict(X) {
return X.map(x => {
const approx = this.dotProduct(x, this.w) - this.b;
return Math.sign(approx);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment