-
Notifications
You must be signed in to change notification settings - Fork 1
/
curfi.min.js
1 lines (1 loc) · 11.3 KB
/
curfi.min.js
1
class Curfi { constructor() { this.modelName = "", this.weights = [], this.weightsLen = 0, this.inputShape = [], this.outputShape = [], this.accuracy = { r2_score: 0 }, this.additionalParams = {} } modelParams(e, t, r, i) { this.weights = [...t], this.modelName = e, this.weightsLen = t.length, this.inputShape = r, this.outputShape = i } modelAccuracy(e) { this.accuracy = { ...e } } modelAdditionalParams(e) { this.additionalParams = { ...e } } loadModel(e) { return this.modelParams(e.modelName, e.weights, e.inputShape, e.outputShape), this.modelAdditionalParams(e.additionalParams), this.modelAccuracy(e.accuracy), this } saveModel(e = "model") { var t = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify({ ...this })), r = document.createElement("a"); r.setAttribute("href", t), r.setAttribute("download", e + ".json"), document.body.appendChild(r), r.click(), r.remove() } fit_AllModels(e, t, r = 3) { let i = { singleX: {}, multiX: {} }; return e.length >= 1 && (i.multiX.MLR = { ...this.fit_MLR(e, t) }, i.multiX.EXP = { ...this.fit_EXP(e, t) }, i.multiX.LogLR = { ...this.fit_LogLR(e, t) }), 1 == e.length && (i.singleX.LR = { ...this.fit_LR(e, t) }, i.singleX.PLR = { ...this.fit_PLR(e, t, r) }, i.singleX.SinLR = { ...this.fit_SinLR(e, t) }), function (e) { for (let t in e) for (let r in e[t]) 0 === Object.keys(e[t][r]).length && e[t][r].constructor === Object || null === e[t][r] || void 0 === e[t][r] ? delete e[t][r] : Number.isNaN(e[t][r].weights[0][0]) && delete e[t][r] }(i), { ...i } } fit_LR(e, t) { return this.fit_LinearRegression(e, t) } fit_LinearRegression(e, t) { let r = this.fit_MultipleLinearRegression(e, t), i = [...r.weights]; this.modelParams("LinearRegression", [...i], e.length, t.length); let s = { r2_score: r.accuracy.r2_score }; return this.modelAccuracy(s), this } fit_MLR(e, t) { return this.fit_MultipleLinearRegression(e, t) } fit_MultipleLinearRegression(e, t) { let r = e[0].length, i = new Array(r).fill(1), s = [...e], l = [...t]; s.unshift(i); let n = e.length, h = [...Array(n + 2)].map(e => Array(n + 2).fill(0)); for (let e = 1; e <= n + 1; e++) { for (let t = 1; t <= e; t++) { let i = 0; for (let l = 0; l < r; l++)i += s[e - 1][l] * s[t - 1][l]; h[e][t] = i, h[t][e] = i } let t = 0; for (let i = 0; i < r; i++)t += l[0][i] * s[e - 1][i]; h[e][n + 2] = t } let o = [], a = []; for (let e = 1; e < h.length; e++) { let t = [], r = []; for (let i = 1; i < h[e].length; i++)i != h[e].length - 1 && t.push(h[e][i]), i == h[e].length - 1 && r.push(h[e][i]); o.push(t), a.push(r) } let u = this.matrix_invert(o); if (-111 === u) return {}; let f = this.matrix_multiply(u, a); this.modelParams("MultipleLinearRegression", [...f], e.length, t.length); let g = { r2_score: this.r2_score(t[0], this.predict(e)[0]) }; return this.modelAccuracy(g), this } fit_EXP(e, t) { return this.fit_ExpLinearRegression(e, t) } fit_ExpLinearRegression(e, t) { let r = e[0].length, i = new Array(r).fill(1), s = 0, l = [...e].map(e => e.map(e => (Math.exp(e) != Number.POSITIVE_INFINITY && Math.exp(e) != Number.NEGATIVE_INFINITY || (s = 1), Math.exp(e)))); if (s) return {}; let n = [...t]; l.unshift(i); let h = e.length, o = [...Array(h + 2)].map(e => Array(h + 2).fill(0)); for (let e = 1; e <= h + 1; e++) { for (let t = 1; t <= e; t++) { let i = 0; for (let s = 0; s < r; s++)i += l[e - 1][s] * l[t - 1][s]; o[e][t] = i, o[t][e] = i } let t = 0; for (let i = 0; i < r; i++)t += n[0][i] * l[e - 1][i]; o[e][h + 2] = t } let a = [], u = []; for (let e = 1; e < o.length; e++) { let t = [], r = []; for (let i = 1; i < o[e].length; i++)i != o[e].length - 1 && t.push(o[e][i]), i == o[e].length - 1 && r.push(o[e][i]); a.push(t), u.push(r) } let f = this.matrix_invert(a); if (-111 === f) return {}; let g = this.matrix_multiply(f, u); this.modelParams("ExponentialLinearRegression", [...g], e.length, t.length); let c = { r2_score: this.r2_score(t[0], this.predict(e)[0]) }; return this.modelAccuracy(c), this } fit_PLR(e, t, r = 3) { return this.fit_PolynomialLinearRegression(e, t, r) } fit_PolynomialLinearRegression(e, t, r = 3) { let i = e[0].length, s = new Array(i).fill(1), l = [...e], n = [...t]; l.unshift(s); let h = [...Array(r + 2)].map(e => Array(r + 2).fill(0)); for (let e = 1; e <= r + 1; e++) { for (let t = 1; t <= e; t++) { let r = e + t - 2, s = 0; for (let e = 0; e < i; e++)s += Math.pow(l[1][e], r); h[e][t] = s, h[t][e] = s } let t = 0; for (let r = 0; r < i; r++)t += n[0][r] * Math.pow(l[1][r], e - 1); h[e][r + 2] = t } let o = [], a = []; for (let e = 1; e < h.length; e++) { let t = [], r = []; for (let i = 1; i < h[e].length; i++)i != h[e].length - 1 && t.push(h[e][i]), i == h[e].length - 1 && r.push(h[e][i]); o.push(t), a.push(r) } let u = this.matrix_invert(o); if (-111 === u) return {}; let f = this.matrix_multiply(u, a); this.modelParams("PolynomialLinearRegression", [...f], e.length, t.length), this.modelAdditionalParams({ order: r }); let g = { r2_score: this.r2_score(t[0], this.predict(e)[0]) }; return this.modelAccuracy(g), this } fit_LogLR(e, t) { return this.fit_LogarithmicLinearRegression(e, t) } fit_LogarithmicLinearRegression(e, t) { let r = e[0].length, i = 0, s = new Array(r).fill(1), l = [...e].map(e => e.map(e => (e <= 0 && (i = 1), Math.log(e)))); if (i) return {}; let n = [...t]; l.unshift(s); let h = e.length, o = [...Array(h + 2)].map(e => Array(h + 2).fill(0)); for (let e = 1; e <= h + 1; e++) { for (let t = 1; t <= e; t++) { let i = 0; for (let s = 0; s < r; s++)i += l[e - 1][s] * l[t - 1][s]; o[e][t] = i, o[t][e] = i } let t = 0; for (let i = 0; i < r; i++)t += n[0][i] * l[e - 1][i]; o[e][h + 2] = t } let a = [], u = []; for (let e = 1; e < o.length; e++) { let t = [], r = []; for (let i = 1; i < o[e].length; i++)i != o[e].length - 1 && t.push(o[e][i]), i == o[e].length - 1 && r.push(o[e][i]); a.push(t), u.push(r) } let f = this.matrix_invert(a); if (-111 === f) return {}; let g = this.matrix_multiply(f, u); this.modelParams("LogarithmicLinearRegression", [...g], e.length, t.length); let c = { r2_score: this.r2_score(t[0], this.predict(e)[0]) }; return this.modelAccuracy(c), this } fit_SinLR(e, t) { return this.fit_SinusoidalRegression(e, t) } fit_SinusoidalRegression(e, t) { let r = e[0].length, i = new Array(r).fill(1), s = [...e].map(e => e.map(e => Math.sin(e * (Math.PI / 180)))), l = [...t]; s.unshift(i), s.push(e[0].map(e => Math.cos(e * (Math.PI / 180)))); let n = s.length - 1, h = [...Array(n + 2)].map(e => Array(n + 2).fill(0)); for (let e = 1; e <= n + 1; e++) { for (let t = 1; t <= e; t++) { let i = 0; for (let l = 0; l < r; l++)i += s[e - 1][l] * s[t - 1][l]; h[e][t] = i, h[t][e] = i } let t = 0; for (let i = 0; i < r; i++)t += l[0][i] * s[e - 1][i]; h[e][n + 2] = t } let o = [], a = []; for (let e = 1; e < h.length; e++) { let t = [], r = []; for (let i = 1; i < h[e].length; i++)i != h[e].length - 1 && t.push(h[e][i]), i == h[e].length - 1 && r.push(h[e][i]); o.push(t), a.push(r) } let u = this.matrix_invert(o); if (-111 === u) return {}; let f = this.matrix_multiply(u, a), g = Math.sqrt(Math.pow(f[1][0], 2) + Math.pow(f[2][0], 2)), c = Math.atan(f[2][0] / f[1][0]) * (180 / Math.PI); f[1][0] = g, f[2][0] = c, this.modelParams("SinusoidalRegression", [...f], e.length, t.length); let m = { r2_score: this.r2_score(t[0], this.predict(e)[0]) }; return this.modelAccuracy(m), this } AutoTrain(e, t, r = null, i = null, s = 3) { let l = this.fit_AllModels(e, t, s), n = { ...{ ...l.multiX }, ...{ ...l.singleX } }, h = []; return Object.keys(n).sort(function (e, t) { return n[t].accuracy.r2_score - n[e].accuracy.r2_score }).forEach(function (e) { if (null === i) { let t = new Curfi; t.loadModel(n[e]), h.push(t) } else if (null !== r && null !== i) { let t = new Curfi; t.loadModel(n[e]), t.accuracy.r2_score_test = t.r2_score(i[0], t.predict(r)[0]), h.push(t) } }), this.loadModel(h[0]), h } predict(e) { let t = [...this.weights], r = []; for (let i = 0; i < e[0].length; i++) { let s = t[0][0]; if ("PolynomialLinearRegression" === this.modelName) for (let r = 0; r < this.additionalParams.order; r++)s += t[r + 1][0] * this.coefficientFunction(e[0][i], r + 1); else for (let r = 0; r < e.length; r++)s += t[r + 1][0] * this.coefficientFunction(e[r][i], r + 1); r.push(s) } return [[...r]] } coefficientFunction(e, t) { switch (this.modelName) { case "LinearRegression": return e; case "PolynomialLinearRegression": return Math.pow(e, t); case "MultipleLinearRegression": return e; case "ExponentialLinearRegression": return Math.exp(e); case "LogarithmicLinearRegression": return Math.log(e); case "SinusoidalRegression": return Math.sin((e + this.weights[t + 1][0]) * Math.PI / 180); default: return e } } r2_score(e, t) { let r = e => isNaN(e) ? 0 : e, i = e.reduce((e, t) => r(e) + r(t)) / e.length, s = 0, l = 0; for (let r = 0; r < e.length; r++)s += (e[r] - i) * (e[r] - i), l += (e[r] - t[r]) * (e[r] - t[r]); return (s - l) / s } round(e, t) { return Math.round((e + Number.EPSILON) * Math.pow(10, t)) / Math.pow(10, t) } round3(e) { return Math.round(1e3 * (e + Number.EPSILON)) / 1e3 } round2(e) { return Math.round(100 * (e + Number.EPSILON)) / 100 } matrix_multiply(e, t) { for (var r = e.length, i = e[0].length, s = (t.length, t[0].length), l = new Array(r), n = 0; n < r; ++n) { l[n] = new Array(s); for (var h = 0; h < s; ++h) { l[n][h] = 0; for (var o = 0; o < i; ++o)l[n][h] += e[n][o] * t[o][h] } } return l } matrix_transpose(e) { var t = e.length || 0, r = e[0] instanceof Array ? e[0].length : 0; if (0 === r || 0 === t) return []; var i, s, l = []; for (i = 0; i < r; i++)for (l[i] = [], s = 0; s < t; s++)l[i][s] = e[s][i]; return l } matrix_invert(e) { if (e.length !== e[0].length) return -111; var t = 0, r = 0, i = 0, s = e.length, l = 0, n = [], h = []; for (t = 0; t < s; t += 1)for (n[n.length] = [], h[h.length] = [], i = 0; i < s; i += 1)n[t][i] = t == i ? 1 : 0, h[t][i] = e[t][i]; for (t = 0; t < s; t += 1) { if (0 == (l = h[t][t])) { for (r = t + 1; r < s; r += 1)if (0 != h[r][t]) { for (i = 0; i < s; i++)l = h[t][i], h[t][i] = h[r][i], h[r][i] = l, l = n[t][i], n[t][i] = n[r][i], n[r][i] = l; break } if (0 == (l = h[t][t])) return -111 } for (i = 0; i < s; i++)h[t][i] = h[t][i] / l, n[t][i] = n[t][i] / l; for (r = 0; r < s; r++)if (r != t) for (l = h[r][t], i = 0; i < s; i++)h[r][i] -= l * h[t][i], n[r][i] -= l * n[t][i] } return n } modelEqnnHTML(e = this, t = this.round3) { this.loadModel(e); let r = ""; switch (this.modelName) { case "LinearRegression": r = `y = (${t(this.weights[0][0])})`; for (let e = 1; e < this.weightsLen; e++)r += ` + (${t(this.weights[e][0])}) x`; return r; case "PolynomialLinearRegression": r = `y = (${t(this.weights[0][0])})`; for (let e = 1; e < this.weightsLen; e++)r += ` + (${t(this.weights[e][0])}) x<sup>${e}</sup>`; return r; case "MultipleLinearRegression": r = `y = (${t(this.weights[0][0])})`; for (let e = 1; e < this.weightsLen; e++)r += ` + (${t(this.weights[e][0])}) x<sub>${e}</sub>`; return r; case "ExponentialLinearRegression": r = `y = (${t(this.weights[0][0])})`; for (let e = 1; e < this.weightsLen; e++)r += ` + (${t(this.weights[e][0])}) e<sup>x<sub>${e}</sub></sup>`; return r; case "LogarithmicLinearRegression": r = `y = (${t(this.weights[0][0])})`; for (let e = 1; e < this.weightsLen; e++)r += ` + (${t(this.weights[e][0])}) log(x<sub>${e}</sub>)`; return r; case "SinusoidalRegression": return r = `y = (${t(this.weights[0][0])}) + (${t(this.weights[1][0])}) Sin(x + (${t(this.weights[2][0])}))`; default: return "Couldn't Create Equation 🌋" } } } if ("undefined" != typeof exports) module.exports = Curfi; else var curfi = Curfi;