UNPKG

@ai-on-browser/data-analysis-models

Version:

Data analysis model package without any dependencies

119 lines (113 loc) 2.4 kB
/** * MONothetic Analysis Clustering */ export default class MONA { // https://stat.ethz.ch/R-manual/R-devel/library/cluster/html/mona.html constructor() {} /** * Number of clusters * @type {number} */ get size() { return this._tree.leafs.length } /** * Initialize model. * @param {Array<Array<0 | 1>>} datas Training data */ init(datas) { this._x = datas this._tree = { idx: this._x.map((_, i) => i), children: [], get leafs() { return this.children.length === 0 ? [this] : this.children.reduce((c, v) => c.concat(v.leafs), []) }, } } /** * Fit model. */ fit() { const leafs = this._tree.leafs const d = this._x[0].length for (const leaf of leafs) { let maxa = -Infinity let maxi = -1 for (let i = 0; i < d; i++) { if (leaf.idx.every(k => this._x[k][i] === this._x[leaf.idx[0]][i])) { continue } let ta = 0 for (let j = 0; j < d; j++) { if (i === j) { continue } let a = 0, b = 0, c = 0, d = 0 for (const idx of leaf.idx) { if (this._x[idx][i] === 1 && this._x[idx][j] === 1) { a++ } else if (this._x[idx][i] === 1 && this._x[idx][j] === 0) { b++ } else if (this._x[idx][i] === 0 && this._x[idx][j] === 1) { c++ } else if (this._x[idx][i] === 0 && this._x[idx][j] === 0) { d++ } } ta += a * d - b * c } if (maxa < ta) { maxa = ta maxi = i } } if (maxi < 0) { continue } const v0 = leaf.idx.filter(v => this._x[v][maxi] === 0) const v1 = leaf.idx.filter(v => this._x[v][maxi] === 1) if (v0.length === 0 || v1.length === 0) { continue } leaf.feature = maxi leaf.children.push( { idx: v0, children: [], get leafs() { return this.children.length === 0 ? [this] : this.children.reduce((c, v) => c.concat(v.leafs), []) }, }, { idx: v1, children: [], get leafs() { return this.children.length === 0 ? [this] : this.children.reduce((c, v) => c.concat(v.leafs), []) }, } ) } } /** * Returns predicted categories. * @returns {number[]} Predicted values */ predict() { const p = [] const leafs = this._tree.leafs for (let k = 0; k < leafs.length; k++) { for (const i of leafs[k].idx) { p[i] = k } } return p } }