/
sma.js
40 lines (35 loc) · 869 Bytes
/
sma.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
/**
* Standardizes Major Axis regression
*/
export default class SMARegression {
// https://oceanone.hatenablog.com/entry/2020/03/25/033101
constructor() {}
/**
* Fit model.
*
* @param {number[]} x Training data
* @param {number[]} y Target values
*/
fit(x, y) {
const n = x.length
const mx = x.reduce((s, v) => s + v, 0) / n
const sx = x.reduce((s, v) => s + (v - mx) ** 2, 0) / n
const my = y.reduce((s, v) => s + v, 0) / n
const sy = y.reduce((s, v) => s + (v - my) ** 2, 0) / n
const sxy = x.reduce((s, v, i) => s + (v - mx) * (y[i] - my), 0) / n
this._a = Math.sqrt(sy / sx)
if (sxy < 0) {
this._a *= -1
}
this._b = my - this._a * mx
}
/**
* Returns predicted values.
*
* @param {number[]} x Sample data
* @returns {number[]} Predicted values
*/
predict(x) {
return x.map(v => this._a * v + this._b)
}
}