Gustafson–Kessel (GK)
Fuzzy clustering with adaptive full covariances—captures ellipsoidal clusters with varying shapes and orientations.
🔍 Overview
Gustafson–Kessel (GK) extends fuzzy c-means by learning a full covariance for each cluster and measuring distances with a scaled Mahalanobis metric. This lets clusters stretch/rotate to fit anisotropic (elliptical) data while keeping a unit-determinant constraint on the induced metric.
⚙️ Class Definition
class soft_clustering.GK(
random_state: int = None,
m: float = 2.0,
max_iter: int = 300,
tol: float = 1e-5,
init: str = 'kmeans++',
reg_covar: float = 1e-6
)
📋 Parameters
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
int |
None |
Seed for reproducible initialization and randomness. |
|
float |
2.0 |
Fuzzifier (>1). Larger values yield softer memberships. |
|
int |
300 |
Maximum number of update iterations. |
|
float |
1e-5 |
Convergence tolerance on absolute improvement of the objective. |
|
str |
‘kmeans++’ |
Initialization strategy for centers/memberships: |
|
float |
1e-6 |
Small ridge added to covariances for numerical stability (positive-definiteness). |
🚀 Usage Examples
from soft_clustering import GK
import numpy as np
np.random.seed(42)
n = 100
# Anisotropic clusters (elliptical) to exercise GK's adaptive covariance
A1 = np.array([[2.0, 0.5],
[0.5, 0.3]])
A2 = np.array([[0.3, -0.4],
[-0.4, 1.5]])
X1 = np.random.randn(n, 2) @ A1 + np.array([0.0, 0.0])
X2 = np.random.randn(n, 2) @ A2 + np.array([3.0, 3.0])
X = np.vstack([X1, X2])
K = 2 # number of clusters
model = GK(random_state=42, max_iter=100, m=2.0, init='kmeans++', reg_covar=1e-6)
memberships = model.fit_predict(X, K)
print("Membership matrix:\n", memberships)
📥 Input / 📤 Output
Input to
fit_predict(X, K)X (np.ndarray or scipy.sparse)of shape(n_samples, n_features); sparse inputs are densified internally.K (int): number of clusters.
Returns
memberships (np.ndarray)of shape(n_samples, K): fuzzy membership degrees (each row sums to 1).
🛠️ Methods
fit_predict(X, K)
Fit the GK model on the provided dataset and return the membership matrix.
At each iteration GK:
estimates fuzzy covariances per cluster using memberships^m,
computes GK distances with a scaled Mahalanobis metric,
updates memberships and then centers (membership-weighted means).
Parameters:
X(numpy.ndarrayorscipy.sparse, shape(n_samples, n_features)): Input data matrix; if sparse, converted to dense internally.K(int): Number of clusters.
Returns:
memberships(np.ndarray, shape(n_samples, K)): Row-normalized fuzzy memberships.
Attributes set on the model:
centers_(np.ndarray, shape(K, n_features)): Final cluster centers.memberships_(np.ndarray, shape(n_samples, K)): Final membership matrix (same as return).covariances_(np.ndarray, shape(K, n_features, n_features)): Learned fuzzy covariances.metrics_A_(np.ndarray, shape(K, n_features, n_features)): Cluster metrics with unit determinant.objective_trajectory_(np.ndarray, shape(t,)): Objective values per iteration.
📝 Implementation Notes
Distance metric (GK): uses a scaled Mahalanobis distance defined by a per-cluster covariance
C_kand a scale factor based on the covariance volume. Concretely, the squared distance is proportional to
det(C_k)^(+1/d) * (x - c_k)^T C_k^{-1} (x - c_k),
which penalizes clusters with larger volumes appropriately and aligns with the standard GK formulation.Unit-determinant metric: the stored metric matrices
A_ksatisfydet(A_k) = 1by setting
A_k = det(C_k)^(+1/d) * C_k^{-1}.Fuzzy covariance update: covariances are computed as membership^m–weighted scatter matrices with a small ridge (
reg_covar) added to the diagonal.Numerical stability: Cholesky factorization is used; if it fails, a tiny positive ridge is added before retrying; distances and denominators are protected with small epsilons.
Initialization:
'kmeans++'(default) starts from seeded centers and uniform memberships;'random'initializes memberships uniformly at random (row-normalized), then derives centers.Convergence: stop when the absolute improvement in the objective ≤
tol, or aftermax_iter.Complexity (per iteration): roughly
O(n * K * d^2)time (due to full covariances) andO(K * d^2 + n * K)memory.
📚 References
D. E. Gustafson, W. C. Kessel (1979). Fuzzy Clustering with a Fuzzy Covariance Matrix. IEEE CDC.
J. C. Bezdek (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. Springer.