/** * Gaussian Mixture Model fitted with full expectation-maximization, * mirroring sklearn.mixture.GaussianMixture (camelCase params). * * The E-step works entirely in the log domain (logsumexp) so responsibilities * never underflow; the M-step re-estimates weights/means/covariances per * covariance type with `regCovar` added to diagonals. Convergence is declared * when the change in average per-sample log-likelihood falls below `tol`; * the best of `nInit` runs (highest lower bound) is kept. */ import { ClusterBase } from '../base/cluster'; import { Params } from '../base/estimator'; import { CovarianceType, Covariances } from './common'; export interface GaussianMixtureProps { /** number of mixture components (default 1) */ nComponents?: number; /** covariance parametrization: 'full' | 'tied' | 'diag' | 'spherical' (default 'full') */ covarianceType?: CovarianceType; /** EM convergence threshold on the average log-likelihood change (default 1e-3) */ tol?: number; /** non-negative regularization added to covariance diagonals (default 1e-6) */ regCovar?: number; /** maximum number of EM iterations (default 100) */ maxIter?: number; /** number of EM restarts; the run with the best log-likelihood wins (default 1) */ nInit?: number; /** responsibility initialization: 'kmeans' | 'random' (default 'kmeans') */ initParams?: 'kmeans' | 'random'; /** seed for reproducible initialization */ randomState?: number; /** user-provided initial weights (length nComponents) */ weightsInit?: number[]; /** user-provided initial means (nComponents × nFeatures) */ meansInit?: number[][]; /** * user-provided initial precisions, shaped per covarianceType: * 'full' k×d×d, 'tied' d×d, 'diag' k×d, 'spherical' k */ precisionsInit?: Covariances; } export declare class GaussianMixture extends ClusterBase { private nComponents; private covarianceType; private tol; private regCovar; private maxIter; private nInit; private initParams; private randomState?; private weightsInit; private meansInit; private precisionsInit; private weights_; private means_; private covariances_; /** whether the best EM run reached the `tol` criterion */ converged: boolean; /** number of EM iterations performed by the best run */ nIter: number; private lowerBound_; private lowerBoundHistory_; constructor(props?: GaussianMixtureProps); getParams(): Params; /** convert user-provided precisions into the covariance container the E-step consumes */ private precisionsToCovariances; private initializeParameters; /** n × k matrix of log(weightₖ) + log N(xᵢ | μₖ, Σₖ) */ private static weightedLogProb; private runEM; fit(X: number[][]): this; private checkFitted; /** hard assignment: argmax of the responsibilities */ predict(X: number[][]): number[]; /** posterior probability (responsibility) of each component for each sample */ predictProba(X: number[][]): number[][]; fitPredict(X: number[][]): number[]; /** per-sample log-likelihood log p(xᵢ) under the mixture */ scoreSamples(X: number[][]): number[]; /** average per-sample log-likelihood */ score(X: number[][]): number; /** number of free parameters, counted exactly like sklearn's `_n_parameters` */ private nParameters; /** Akaike information criterion: −2·logL + 2·nParams (lower is better) */ aic(X: number[][]): number; /** Bayesian information criterion: −2·logL + ln(n)·nParams (lower is better) */ bic(X: number[][]): number; getWeights(): number[] | null; getMeans(): number[][] | null; getCovariances(): Covariances | null; /** average per-sample log-likelihood of the best EM run at its final E-step */ getLowerBound(): number; /** lower-bound trajectory of the best EM run (one entry per iteration, non-decreasing) */ getLowerBoundHistory(): number[]; }