UNPKG

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

Version:

Data analysis model package without any dependencies

88 lines (79 loc) 1.72 kB
import { KMeanspp } from './kmeans.js' import LaplacianEigenmaps from './laplacian_eigenmaps.js' /** * Spectral clustering */ export default class SpectralClustering { // https://mr-r-i-c-e.hatenadiary.org/entry/20121214/1355499195 /** * @param {'rbf' | 'knn' | { name: 'rbf', sigma?: number, k?: number } | { name: 'knn', k?: number }} [affinity] Affinity type name */ constructor(affinity = 'rbf') { this._size = 0 this._epoch = 0 this._clustering = new KMeanspp() this._affinity = affinity } /** * Number of clusters. * @type {number} */ get size() { return this._size } /** * Epoch. * @type {number} */ get epoch() { return this._epoch } /** * Initialize model. * @param {Array<Array<number>>} datas Training data */ init(datas) { const n = datas.length this._n = n const le = new LaplacianEigenmaps(datas[0].length, this._affinity, 'normalized') this.ready = false le.predict(datas) this._ev = le._ev this._ev.flip(1) } /** * Add a new cluster. */ add() { this._size++ this._clustering.clear() const s_ev = this._ev.slice(this._n - this._size, this._n, 1) this._s_ev = s_ev.toArray() for (let i = 0; i < this._size; i++) { this._clustering.add(this._s_ev) } } /** * Clear all clusters. */ clear() { this._size = 0 this._epoch = 0 this._clustering.clear() } /** * Returns predicted categories. * @returns {number[]} Predicted values */ predict() { return this._clustering.predict(this._s_ev) } /** * Fit and returns total distance the centroid has moved. * @returns {number} Total distance the centroid has moved */ fit() { this._epoch++ return this._clustering.fit(this._s_ev) } }