glm
Version:
Generalized Linear Models
137 lines (120 loc) • 6.01 kB
HTML
<html>
<head>
<link type="text/css" rel="stylesheet" href="basic.css">
<script src="d3.v2.js"></script>
<script src="../../glm.js"></script>
<script src="jquery.min.js"></script>
</head>
<body>
<h1>Horsepower v. MPG for Cars</h1>
<p>The chart shows a logistic curve fit between the horsepower and miles per gallon for individal cars in the <a href="http://stat.ethz.ch/R-manual/R-patched/library/datasets/html/mtcars.html">Motor Trend Car Road Test dataset</a>. Instead of using the raw horsepower value from the dataset, we convert it to a binary value. If it is below a certain cutoff point the assigned value is 0, otherwise 1. Use the slider to adjust this cutoff value and watch how the logistic curve changes.</p>
<p>Use the slider to choose a horsepower to divide the dataset.</p>
<p>HP: <input type="range" min="60" max="340" id="binSplitter" value="125" /> <span id="mpgValue"> </span> </p>
<div id="chart-container"></div>
<div id="information-container">
<h1> Cars with HP greater than threshold </h1>
<ul id="greater-than-threshold-list"> </ul>
<h1> Cars with HP less than threshold </h1>
<ul id="less-than-threshold-list"> </ul>
</div>
</body>
<script>
// extracted from motortrends cars dataset
var cars = {mpg: [21.0,21.0,22.8,21.4,18.7,18.1,14.3,24.4,22.8,19.2,17.8,16.4,17.3,15.2,10.4,10.4,14.7,32.4,30.4,33.9,21.5,15.5,15.2,13.3,19.2,27.3,26.0,30.4,15.8,19.7,15.0,21.4], hp: [110,110,93,110,175,105,245,62,95,123,123,180,180,180,205,215,230,66,52,65,97,150,150,245,175,66,91,113,264,175,335,109], names: [ "Mazda RX4", "Mazda RX4 Wag", "Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", "Valiant", "Duster 360", "Merc 240D", "Merc 230", "Merc 280", "Merc 280C", "Merc 450SE", "Merc 450SL", "Merc 450SLC", "Cadillac Fleetwood", "Lincoln Continental", "Chrysler Imperial", "Fiat 128", "Honda Civic", "Toyota Corolla", "Toyota Corona", "Dodge Challenger", "AMC Javelin", "Camaro Z28", "Pontiac Firebird", "Fiat X1-9", "Porsche 914-2", "Lotus Europa", "Ford Pantera L", "Ferrari Dino", "Maserati Bora", "Volvo 142E"]};
function binarizer(data) {
// get split value from DOM
var mid = parseInt(document.getElementById('binSplitter').value);
return GLM.utils.map(data, function (x) { return (x > mid) ? 1 : 0; });
}
function makeArray(data) {
var mpg = data.mpg, hp = binarizer(data.hp), names = data.names;
return GLM.utils.map(mpg, function (m, i) { return {x: m, y: hp[i], name: names[i]}; });
}
var w = 480, h = 275, p = 20,
lowerBound = d3.min(cars.mpg), upperBound = d3.max(cars.mpg);
x = d3.scale.linear().domain([lowerBound, upperBound]).range([0, w]),
y = d3.scale.linear().domain([0, 1]).range([h, 0]);
var vis = d3.select("#chart-container")
.data([cars])
.append("svg:svg")
.attr("width", w + p * 2)
.attr("height", h + p * 2)
.append("svg:g")
.attr("transform", "translate(" + p + "," + p + ")");
vis.append("text")
.attr("x", w / 2 - 15)
.attr("y", h + 20)
.text("Miles Per Gallon");
vis.append("g")
.attr("transform", "translate(0," + h / 2 + ")")
.append("text")
.attr("transform", "rotate(270)")
.text("Binarized Horsepower");
var rules = vis.selectAll("g.rule")
.data(x.ticks(10))
.enter().append("svg:g")
.attr("class", "rule");
rules.append("svg:line")
.attr("x1", x)
.attr("x2", x)
.attr("y1", 0)
.attr("y2", h - 1);
rules.append("svg:line")
.attr("class", function(d) { return d ? null : "axis"; })
.attr("y1", y)
.attr("y2", y)
.attr("x1", 0)
.attr("x2", w + 1);
rules.append("svg:text")
.attr("x", x)
.attr("y", h + 3)
.attr("dy", ".71em")
.attr("text-anchor", "middle")
.text(x.tickFormat(10));
rules.append("svg:text")
.attr("y", y)
.attr("x", -3)
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(y.tickFormat(10));
var circles = vis.selectAll("circle.line")
.data(makeArray(cars))
.enter().append("svg:circle")
.attr("class", "line")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", 3.5);
circles.append("title").text(function(d) { return d.name });
var line = d3.svg.line()
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
function circlizer() {
this.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", 3.5);
}
var path = vis.append("svg:path")
.attr("class", "line");
function createPathAndMoveBubbles() {
var binaryHpValues = binarizer(cars.hp),
glm = GLM(GLM.families.Binomial()).fit(binaryHpValues, cars.mpg),
glm_data = GLM.utils.map(GLM.utils.linspace(lowerBound, upperBound, 200), function (x) {
return {x: x, y: glm.predict([x])[0]};
});
circles.data(makeArray(cars)).transition().call(circlizer);
path.attr("d", line(glm_data));
$("#mpgValue").html($('#binSplitter').val());
$("#greater-than-threshold-list").html("");
$("#less-than-threshold-list").html("");
GLM.utils.map(binaryHpValues, function (binaryhp, i) {
if (binaryhp == 1) {
$("#greater-than-threshold-list").append("<li>" + cars.names[i] + "</li>");
} else {
$("#less-than-threshold-list").append("<li>" + cars.names[i] + "</li>");
}
});
}
createPathAndMoveBubbles();
$('#binSplitter').change(createPathAndMoveBubbles);
</script>
</html>