/
quantile_regression.js
57 lines (51 loc) · 1.33 KB
/
quantile_regression.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
import Matrix from '../util/matrix.js'
/**
* Quantile regression
*/
export default class QuantileRegression {
// https://salad-bowl-of-knowledge.github.io/hp/statistics/2020/01/21/quantile_regression.html
// https://en.wikipedia.org/wiki/Quantile_regression
/**
* @param {number} [tau] Quantile value
*/
constructor(tau = 0.5) {
this._tau = tau
this._w = null
}
/**
* Fit model.
*
* @param {Array<Array<number>>} x Training data
* @param {Array<Array<number>>} y Target values
* @param {number} [learningRate] Learning rate
*/
fit(x, y, learningRate = 0.1) {
x = Matrix.fromArray(x)
y = Matrix.fromArray(y)
const n = x.rows
const xh = Matrix.resize(x, n, x.cols + 1, 1)
if (this._w === null) {
this._w = Matrix.randn(xh.cols, y.cols)
}
const p = xh.dot(this._w)
const d = Matrix.sub(y, p)
const indicator = Matrix.map(d, v => (v <= 0 ? 1 : 0))
const g = Matrix.sub(indicator, this._tau)
g.map(v => Math.abs(v))
g.mult(Matrix.map(d, v => Math.sign(v)))
const dw = xh.tDot(g)
dw.mult(learningRate)
this._w.add(dw)
}
/**
* Returns predicted values.
*
* @param {Array<Array<number>>} x Sample data
* @returns {Array<Array<number>>} Predicted values
*/
predict(x) {
x = Matrix.fromArray(x)
const xh = Matrix.resize(x, x.rows, x.cols + 1, 1)
return xh.dot(this._w).toArray()
}
}