summaryrefslogtreecommitdiff
path: root/code/bostonset.js
blob: f5f1264d471e60cef80aa17a1f0d9a876c624ed5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
var Bostonset = (function() {
    var attrs =
        ["crim", "zn", "indus", "chas", "nox", "rm", "age", "dis", "rad", "tax", "ptratio", "black", "lstat", "medv"];

    function Bostonset() {
        this.data = [];
        // fixed constants exported from training data
        this.dataScaler = new MinMaxScaler();
        this.dataScaler.setScales([[0.00632, 0.0, 0.46, 0.0, 0.385, 3.561, 2.9, 1.1296, 1.0, 187.0, 12.6, 0.32, 1.73], [88.9762, 100.0, 27.74, 1.0, 0.871, 8.78, 100.0, 12.1265, 24.0, 711.0, 22.0, 396.9, 37.97]]);
        this.targetScaler = new MinMaxScaler();
        this.targetScaler.setScales([5.0, 50.0]);
        this.readyHooks = [];
    }

    Bostonset.prototype.load = function(url) {
        var self = this;
        d3.csv(url).get(function(e, data) {
            if (e) console.log(e);
            data.forEach(function (el) {
                var arr = [];
                for (c=0; c<attrs.length; c++) {
                    arr.push(parseFloat(el[attrs[c]]));
                }
                self.data.push(arr);
            });
            self.readyHooks.forEach(function(hook) { hook(); });
        });
    };

    Bostonset.prototype.afterLoad = function(cb) {
        if (!this.ready) {
            this.readyHooks.push(cb);
        } else {
            cb();
        }
    };

    Bostonset.prototype.attributes = function() {
        console.log(attrs);
        return attrs;
    };

    Bostonset.prototype.length = function() {
        return this.data.length;
    };

    Bostonset.prototype.rawData = function(row) {
        return this.data[row];
    };

    Bostonset.prototype.rawInputs = function(row) {
        return this.rawData(row).slice(0, -1); // leave out MEDV
    };

    Bostonset.prototype.inputs = function(row) {
        return this.dataScaler.scale(this.rawInputs(row));
    };

    Bostonset.prototype.asOutput = function(num) {
        return this.targetScaler.unscale(num);
    };

    Bostonset.prototype.expectedOutput = function(row) {
        return this.data[row][attrs.length-1];
    };

    return Bostonset;
})();

// TODO abstract for generic shapes?
var MinMaxScaler = (function() {
    function MinMaxScaler() {
    }

    MinMaxScaler.prototype.fit = function(arr) {
        this.setScales(d3.extent(arr));
    };

    MinMaxScaler.prototype.setScales = function(fits) {
        this.min = fits[0];
        this.max = fits[1];
    };

    MinMaxScaler.prototype.scale = function(data) {
        data = this._arrayDivide(this._arraySubtract(data, this.min), this._arraySubtract(this.max, this.min));
        return data;
    };

    MinMaxScaler.prototype.unscale = function(data) {
        data = this._arrayAdd(this._arrayMultiply(data, this._arraySubtract(this.max, this.min)), this.min);
        return data;
    };

    MinMaxScaler.prototype._arraySubtract = function(one, two) {
        if (one.constructor !== Array) return one - two;
        for (i=0; i<one.length; one[i]-=two[i++]);
        return one;
    };

    MinMaxScaler.prototype._arrayAdd = function(one, two) {
        if (one.constructor !== Array) return one + two;
        for (i=0; i<one.length; one[i]+=two[i++]);
        return one;
    };

    MinMaxScaler.prototype._arrayMultiply = function(one, two) {
        if (one.constructor !== Array) return one * two;
        for (i=0; i<one.length; one[i]*=two[i++]);
        return one;
    };

    MinMaxScaler.prototype._arrayDivide = function(one, two) {
        if (one.constructor !== Array) return one / two;
        for (i=0; i<one.length; one[i]/=two[i++]);
        return one;
    };

    return MinMaxScaler;
})();