Last active
April 13, 2017 07:29
-
-
Save jonahwilliams/810d8d84278539952369 to your computer and use it in GitHub Desktop.
Under-fitting versus Over-fitting
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> | |
<style> | |
.axis { | |
font: 10px sans-serif; | |
} | |
path { | |
stroke: steelblue; | |
stroke-width: 2; | |
fill: none; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
</style> | |
</head> | |
<body> | |
<form> | |
<label id="label">0 Degree Polynomial</label> | |
<input type="range" id="points" min="0" max="25" value="0"> | |
</form> | |
<script src="LinearRegression.js"></script> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
var data = []; | |
for (var i = 0; i < 20; i++){ | |
var a = 6 * Math.random(); | |
data.push({'x': a,'y': 0.9 * Math.sin(a) + (0.25 * Math.random()) - 0.125}); | |
} | |
var degree = document.getElementById("points").value; | |
var newdata = BasisExpand(data, degree); | |
var params = LinearRegression(newdata); | |
var smoothed = []; | |
for (var i = 1; i < 600; i++){ | |
var val = BasisExpand([{'x':(6/600) * i, 'y':0}], degree); | |
var y = 0.0; | |
for (var j = 0; j < params.length; j++){ | |
y += params[j][0] * val[0].x[j]; | |
} | |
smoothed.push({'x':(6/600) * i, 'y': y}); | |
} | |
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([-1, 1]) | |
.range([height, 0]); | |
var x = d3.scale.linear() | |
.domain([0, 6]) | |
.range([0, width]) | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.orient("bottom"); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.orient("left"); | |
var line = d3.svg.line() | |
.x(function(d) { return x(d.x); }) | |
.y(function(d) { return y(d.y); }); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis) | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis); | |
svg.selectAll(".dot") | |
.data(data) | |
.enter().append("circle") | |
.attr("class", "dot") | |
.attr("r", 3.5) | |
.attr("cx", function(d){ | |
return x(d.x); | |
}) | |
.attr("cy", function(d){ | |
return y(d.y) | |
}) | |
.style("fill", "black"); | |
svg.append("path") | |
.datum(smoothed) | |
.attr("class", "line") | |
.attr("d", line); | |
d3.select("#points") | |
.on("change", function(d){ | |
var degree = document.getElementById("points").value; | |
d3.select("label") | |
.text(degree + " Degree Polynomial"); | |
var newdata = BasisExpand(data, degree); | |
var params = LinearRegression(newdata); | |
var smoothed = []; | |
for (var i = 1; i < 100; i++){ | |
var val = BasisExpand([{'x':(6/100) * i, 'y':0}], degree); | |
var y = 0.0; | |
for (var j = 0; j < params.length; j++){ | |
y += params[j][0] * val[0].x[j]; | |
} | |
smoothed.push({'x':(6/100) * i, 'y': y}); | |
} | |
svg.selectAll(".line") | |
.datum(smoothed) | |
.transition() | |
.attr("class", "line") | |
.attr("d", line); | |
}) | |
function BasisExpand(data, degree){ | |
var BasisData = []; | |
for (var i = 0; i < data.length; i++){ | |
var expanded = {'x':[], 'y': data[i].y}; | |
for (var j = 0; j <= degree; j++){ | |
expanded['x'].push(Math.pow(data[i].x - 3, j)); | |
} | |
BasisData.push(expanded); | |
} | |
return BasisData; | |
} | |
</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
function LinearRegression(data){ | |
var X = [], | |
y = []; | |
for (var i = 0; i < data.length; i ++){ | |
var tempX = []; | |
for(var j = 0; j < data[0]['x'].length; j++){ | |
tempX.push(data[i]['x'][j]); | |
} | |
X.push(tempX); | |
y.push([data[i].y]); | |
} | |
var t = matrixTranspose(X); | |
var hat = matrixMultiply(matrixMultiply(matrixInvert(matrixMultiply(t, X)), t), y); | |
return hat; | |
} | |
function matrixTranspose(a){ | |
//http://stackoverflow.com/questions/4492678/to-swap-rows-with-columns-of-matrix-in-javascript-or-jquery | |
return Object.keys(a[0]).map( | |
function (c) { return a.map(function (r) { return r[c]; }); } | |
); | |
} | |
function matrixMultiply(m1, m2) { | |
// http://tech.pro/tutorial/1527/matrix-multiplication-in-functional-javascript | |
// | |
var result = []; | |
for (var i = 0; i < m1.length; i++) { | |
result[i] = []; | |
for (var j = 0; j < m2[0].length; j++) { | |
var sum = 0; | |
for (var k = 0; k < m1[0].length; k++) { | |
sum += m1[i][k] * m2[k][j]; | |
} | |
result[i][j] = sum; | |
} | |
} | |
return result; | |
} | |
function matrixInvert(M){ | |
// source - http://blog.acipo.com/matrix-inversion-in-javascript/ | |
// | |
if(M.length !== M[0].length){return;} | |
var i=0, ii=0, j=0, dim=M.length, e=0, t=0; | |
var I = [], C = []; | |
for(i=0; i<dim; i+=1){ | |
I[I.length]=[]; | |
C[C.length]=[]; | |
for(j=0; j<dim; j+=1){ | |
if(i==j){ I[i][j] = 1; } | |
else{ I[i][j] = 0; } | |
C[i][j] = M[i][j]; | |
} | |
} | |
for(i=0; i<dim; i+=1){ | |
e = C[i][i]; | |
if(e==0){ | |
for(ii=i+1; ii<dim; ii+=1){ | |
if(C[ii][i] != 0){ | |
for(j=0; j<dim; j++){ | |
e = C[i][j]; | |
C[i][j] = C[ii][j]; | |
C[ii][j] = e; | |
e = I[i][j]; | |
I[i][j] = I[ii][j]; | |
I[ii][j] = e; | |
} | |
break; | |
} | |
} | |
e = C[i][i]; | |
if(e==0){return} | |
} | |
for(j=0; j<dim; j++){ | |
C[i][j] = C[i][j]/e; | |
I[i][j] = I[i][j]/e; | |
} | |
for(ii=0; ii<dim; ii++){ | |
if(ii==i){continue;} | |
e = C[ii][i]; | |
for(j=0; j<dim; j++){ | |
C[ii][j] -= e*C[i][j]; | |
I[ii][j] -= e*I[i][j]; | |
} | |
} | |
} | |
return I; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment