/** @import { InputType } from "../index.js" */ /** @import { ParametersXMeans } from "./index.js" */ /** * @typedef SplitResult * @property {number} index - Index of the cluster being split * @property {number} bic_parent - BIC score of the parent cluster * @property {number} bic_children - BIC score of the split children * @property {number[][]} child_clusters - Clusters after splitting * @property {Float64Array[]} child_centroids - Centroids of child clusters */ /** * @typedef CandidateResult * @property {KMeans} kmeans - The KMeans instance for this K * @property {number} score - BIC score */ /** * X-Means Clustering * * An extension of K-Means that automatically determines the number of clusters (K) * using the Bayesian Information Criterion (BIC). * * @class * @extends Clustering * @category Clustering */ export class XMeans extends Clustering { /** * XMeans clustering algorithm that automatically determines the optimal number of clusters. * * X-Means extends K-Means by starting with a minimum number of clusters and iteratively * splitting clusters to improve the Bayesian Information Criterion (BIC). * * Algorithm: * 1. Start with K_min clusters using KMeans * 2. For each cluster, try splitting it into 2 sub-clusters * 3. If BIC improves after splitting, keep the split * 4. Run KMeans again with all (old + new) centroids * 5. Repeat until K_max is reached or no more improvements * * @param {InputType} points - The data points to cluster * @param {Partial} [parameters={}] - Configuration parameters * @see {@link https://www.cs.cmu.edu/~dpelleg/download/xmeans.pdf} * @see {@link https://github.com/annoviko/pyclustering/blob/master/pyclustering/cluster/xmeans.py} * @see {@link https://github.com/haifengl/smile/blob/master/core/src/main/java/smile/clustering/XMeans.java} */ constructor(points: InputType, parameters?: Partial); _randomizer: Randomizer; /** @type {KMeans | null} */ _best_kmeans: KMeans | null; /** * Run the XMeans algorithm * * @private */ private _run; /** * Select the best candidate based on BIC score * * @private * @param {Map} candidates * @returns {KMeans} */ private _select_best_candidate; /** * Calculate Bayesian Information Criterion for a set of clusters. * * Uses Kass's formula for BIC calculation: * BIC(θ) = L(D) - 0.5 * p * ln(N) * * Where: * - L(D) is the log-likelihood of the data * - p is the number of free parameters: (K-1) + D*K + 1 * - N is the total number of points * * @private * @param {number[][]} clusters - Array of clusters with point indices * @param {Float64Array[]} centroids - Array of centroids * @returns {number} BIC score (higher is better) */ private _bic; /** * Get the computed clusters * * @returns {number[][]} Array of clusters, each containing indices of points */ get_clusters(): number[][]; /** @returns {number[]} The cluster list */ get_cluster_list(): number[]; /** * Get the final centroids * * @returns {Float64Array[]} Array of centroids */ get centroids(): Float64Array[]; /** * Get the optimal number of clusters found * * @returns {number} The number of clusters */ get k(): number; } export type SplitResult = { /** * - Index of the cluster being split */ index: number; /** * - BIC score of the parent cluster */ bic_parent: number; /** * - BIC score of the split children */ bic_children: number; /** * - Clusters after splitting */ child_clusters: number[][]; /** * - Centroids of child clusters */ child_centroids: Float64Array[]; }; export type CandidateResult = { /** * - The KMeans instance for this K */ kmeans: KMeans; /** * - BIC score */ score: number; }; import type { ParametersXMeans } from "./index.js"; import { Clustering } from "./Clustering.js"; import { Randomizer } from "../util/index.js"; import { KMeans } from "./KMeans.js"; import type { InputType } from "../index.js"; //# sourceMappingURL=XMeans.d.ts.map