/
robust_scaler.js
65 lines (62 loc) · 1.44 KB
/
robust_scaler.js
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
/**
* Robust scaler
*/
export default class RobustScaler {
constructor() {
this._q_low = 0.25
this._q_high = 0.75
}
_q(x, p) {
const np = (x.length - 1) * p
const np_l = Math.floor(np)
const np_h = Math.ceil(np)
return x[np_l] + (np - np_l) * (x[np_h] - x[np_l])
}
/**
* Fit model.
*
* @param {number[] | Array<Array<number>>} x Training data
*/
fit(x) {
if (Array.isArray(x[0])) {
this._mid = []
this._ql = []
this._qh = []
for (let i = 0; i < x[0].length; i++) {
const xi = x.map(r => r[i])
xi.sort((a, b) => a - b)
this._mid[i] = this._q(xi, 0.5)
this._ql[i] = this._q(xi, this._q_low)
this._qh[i] = this._q(xi, this._q_high)
}
} else {
x = x.concat()
x.sort((a, b) => a - b)
this._mid = this._q(x, 0.5)
this._ql = this._q(x, this._q_low)
this._qh = this._q(x, this._q_high)
}
}
/**
* Returns transformed values.
*
* @param {number[] | Array<Array<number>>} x Sample data
* @returns {number[] | Array<Array<number>>} Predicted values
*/
predict(x) {
return x.map(r => {
if (Array.isArray(r)) {
if (Array.isArray(this._mid)) {
return r.map((v, i) => (v - this._mid[i]) / (this._qh[i] - this._ql[i]))
} else {
return r.map(v => (v - this._mid) / (this._qh - this._ql))
}
}
if (Array.isArray(this._mid)) {
return (r - this._mid[0]) / (this._qh[0] - this._ql[0])
} else {
return (r - this._mid) / (this._qh - this._ql)
}
})
}
}