Implementation of a perceptron classifier on a linearly separable dataset. The decision boundary of the classifier Sign(wx + b) is given at wx + b = 0, where w is a vector of weights, x is a vector of points, and b is the bias (intercept) term. Each step is 20 iterations of the simpliest perceptron learning algorithm; misclassified points have black outlines and correctly classified points no longer contribute to gradient adjustment. This means that the decision boundary will no longer move once all points are classified correctly, and many different decision boundaries are possible.
Last active
August 29, 2015 14:21
-
-
Save jonahwilliams/60eecef5e9f721348c20 to your computer and use it in GitHub Desktop.
Perceptron Learning I
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<style> | |
.axis { | |
font: 10px sans-serif; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
</style> | |
</head> | |
<body> | |
<div align="center"> | |
<button type="button" onclick="UpdatePerceptron()">Iterate</button> | |
</div> | |
<script> | |
var m = {'x': 0.001, 'y': 0.001}, | |
b = 0, | |
alpha = 0.01; | |
var margin = {top: 80, right: 180, bottom: 80, left: 180}, | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var y = d3.scale.linear() | |
.domain([0, 10]) | |
.range([height, 0]); | |
var x = d3.scale.linear() | |
.domain([0, 10]) | |
.range([0, width]) | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.orient("bottom"); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.orient("left"); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis) | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis); | |
decision = svg.append("line") | |
.attr("class", "line") | |
.attr("x1", function(d){ | |
return x(0); | |
}) | |
.attr("x2", function(d){ | |
return x(10); | |
}) | |
.attr("y1", function(d){ | |
return y(-b / m.y); | |
}) | |
.attr("y2", function(d){ | |
return y(((-m.x / m.y) * 10) - (b / m.y)); | |
}) | |
.style("stroke", "black") | |
.style("stroke-width", 1); | |
d3.json("PerceptronClassifier.json", function(error, data){ | |
dots = svg.selectAll(".dot") | |
.data(data) | |
.enter().append("circle") | |
.attr("class", "dot") | |
.attr("r", 5.5) | |
.attr("cx", function(d){ | |
return x(+d.x); | |
}) | |
.attr("cy", function(d){ | |
return y(+d.y) | |
}) | |
.style("fill", function(d){ | |
if (d.c == 1){ | |
return "#377eb8"; | |
} | |
else { | |
return "#e41a1c"; | |
} | |
}) | |
.style("stroke", function(d){ | |
var u = d.c * ((m.x * d.x) + (m.y * d.y) + b); | |
if (u >= 0){ | |
return "white"; | |
} | |
else{ | |
return "black"; | |
console.log(d.x, d.y, d.c); | |
} | |
}) | |
.style("stroke-width", 2); | |
}); | |
function OfflineLearning(data, alpha){ | |
//Takes dataset and setpsize alpha | |
var delta = [0, 0, 0]; | |
for (var i = 0; i < data.length; i++){ | |
var d = data[i]; | |
var u = d.c * ((m.x * d.x) + (m.y * d.y) + b); | |
if ( u <= 0){ | |
delta[0] += (d.c - f) * d.x; | |
delta[1] += (d.c - f) * d.y; | |
delta[2] += (d.c - f); | |
} | |
} | |
for (var i = 0; i < delta; i ++){ | |
delta[i] /= data.length | |
} | |
m.x = m.x + alpha * delta[0]; | |
m.y = m.y + alpha * delta[1]; | |
b = b + alpha * delta[2]; | |
return [m, b]; | |
} | |
function OnlineLearning(data, alpha, n){ | |
//Takes a dataset, a setpsize alpha, and a number of iterations to performs, | |
//Otherwise far too slow to see effect | |
for (var i = 0; i < n; i++){ | |
var d = data[Math.floor(Math.random() * data.length)]; | |
var u = (m.x * d.x) + (m.y * d.y) + b; | |
if (d.c * u <= 0){ | |
m.x = m.x + alpha * d.c * d.x; | |
m.y = m.y + alpha * d.c * d.y; | |
b = b + alpha * d.c; | |
} | |
} | |
return [m, b]; | |
} | |
function UpdatePerceptron(){ | |
d3.json("PerceptronClassifier.json", function(error, data){ | |
ret = OnlineLearning(data, alpha, 10); | |
m = ret[0]; | |
b = ret[1]; | |
decision.transition() | |
.ease("linear") | |
.attr("y1", function(d){ | |
return y(-b / m.y); | |
}) | |
.attr("y2", function(d){ | |
return y(((-m.x / m.y) * 10) - (b / m.y)); | |
}); | |
dots.transition() | |
.ease("linear") | |
.style("stroke", function(d){ | |
var u = d.c * ((m.x * d.x) + (m.y * d.y) + b); | |
if (u >= 0){ | |
return "white"; | |
} | |
else{ | |
return "black"; | |
console.log(d.x, d.y, d.c); | |
} | |
}); | |
}); | |
} | |
</script> | |
</body> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[{"x":1.3918159586,"y":2.3137462987,"c":-1},{"x":2.7553492977,"y":3.8358933062,"c":-1},{"x":1.3068825052,"y":1.562141254,"c":-1},{"x":2.8944226465,"y":2.5841533943,"c":-1},{"x":3.7024428812,"y":2.7501198675,"c":-1},{"x":3.5026863304,"y":4.1441852379,"c":-1},{"x":1.2875267989,"y":1.6449839313,"c":-1},{"x":1.5512224368,"y":3.479681808,"c":-1},{"x":2.4134867529,"y":4.2236237896,"c":-1},{"x":3.6559341255,"y":1.9783436371,"c":-1},{"x":6.9659900849,"y":5.3009901301,"c":1.0},{"x":9.0119210614,"y":7.702946096,"c":1.0},{"x":5.950966712,"y":7.2311001543,"c":1.0},{"x":5.979236673,"y":7.7339372771,"c":1.0},{"x":5.955605886,"y":6.8574976596,"c":1.0},{"x":7.8664572356,"y":6.3242365141,"c":1.0},{"x":5.2714950518,"y":6.744864841,"c":1.0},{"x":7.0457948624,"y":8.2216029477,"c":1.0},{"x":8.3580121873,"y":7.1820232618,"c":1.0},{"x":9.6273291291,"y":7.0579781464,"c":1.0}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment