7 Revolutionary Advancements in Functional Data Clustering with Fdmclust (And What’s Holding It Back)

Funclust on ECG signals

Introduction: The Evolution of Functional Data Clustering

In the era of big data, functional data analysis (FDA) has emerged as a powerful tool for analyzing datasets where observations are curves, images, or other continuous functions. Traditional clustering techniques often fall short when applied to such high-dimensional, non-Euclidean data. This is where Fdmclust —a novel clustering algorithm based on functional data model-based clustering—comes into play. By leveraging Reproducing Kernel Hilbert Space (RKHS) and advanced probability density approximations, Fdmclust provides a robust framework for clustering both Gaussian and non-Gaussian functional data .

In this article, we explore the seven revolutionary advancements offered by Fdmclust while also discussing the limitations that still need to be addressed. Whether you’re a data scientist working on climate modeling, a bioinformatician analyzing time-series gene expression, or an AI researcher building predictive models, understanding Fdmclust could transform how you handle functional data.


1. 🌟 Revolutionary Advancement: Enhanced Probability Density Approximation in RKHS

Fdmclust introduces a new probability density approximation for functional random variables in a Reproducing Kernel Hilbert Space (RKHS). Unlike traditional methods that rely on the covariance kernel under the assumption of Gaussianity, Fdmclust uses the Mercer kernel to project functional data. This allows for a more flexible and accurate modeling of data structures, especially when dealing with non-linear dependencies .

Key Equation: Probability Density Approximation in Fdmclust

$$df(g) = \prod_{j=1}^{q} d_{Z_j}(z_j)$$

Where:

  • df(g) : Estimated density of function f at function g
  • dZj​​(zj​) : Density of the independent component Zj at value zj
  • q : Number of components retained after projection

This approach allows Fdmclust to capture complex, non-Gaussian structures that traditional methods like Funclust or funHDDC fail to model accurately.


2. 🌟 Revolutionary Advancement: Dual Strategy for Gaussian and Non-Gaussian Data

One of the standout features of Fdmclust is its ability to handle both Gaussian and non-Gaussian functional data seamlessly. It employs Principal Component Analysis (PCA) for Gaussian data and Independent Component Analysis (ICA) for non-Gaussian data. This dual-strategy approach ensures that the clustering is not biased toward any specific data distribution.

Why This Matters:

  • Gaussian Data : PCA removes correlations and retains variance.
  • Non-Gaussian Data : ICA captures statistical independence, crucial for real-world data like financial time series or EEG signals.

This flexibility makes Fdmclust suitable for a wide range of applications, from climate modeling to medical diagnostics .


3. 🌟 Revolutionary Advancement: Superior Clustering Performance on Real-World Datasets

The paper evaluates Fdmclust on both simulated and real datasets , including:

  • Waves (synthetic curves)
  • ECG (medical time series)
  • Growth curves (pediatric data)
  • Canadian temperature (climate data)
  • Wind speed (meteorological data)

Performance Metrics:

DATASETFDMCLUST R1FUNCLUST R1FUNHDDC R1
Waves1.000.810.85
ECG0.640.570.56
Growth0.550.690.70
Canadian Temp.297.06 MSD313.23 MSD301.21 MSD

RI = Rand Index, MSD = Mean Square Distance

Fdmclust consistently outperforms other methods, especially in high-dimensional and noisy environments .


4. 🌟 Revolutionary Advancement: Mercer Kernel vs. Covariance Kernel

Traditional functional clustering methods rely on the covariance kernel , which assumes linear relationships between variables. Fdmclust, however, uses the Mercer kernel , which can model non-linear dependencies more effectively.

Key Difference:

  • Covariance Kernel : Suitable for linear, Gaussian data only.
  • Mercer Kernel : General-purpose, captures non-linear structures.

This makes Fdmclust particularly effective for complex datasets like those in climate science , where variables like temperature, humidity, and wind speed interact in non-linear ways.


5. 🌟 Revolutionary Advancement: EM Algorithm-Based Model Estimation

Fdmclust employs the Expectation-Maximization (EM) algorithm to estimate model parameters, ensuring robustness and convergence. The EM algorithm iteratively refines the cluster assignments and model parameters, leading to accurate and stable clustering results .

EM Algorithm Steps:

  1. E-step : Compute posterior probabilities of cluster membership.
  2. M-step : Update model parameters based on posterior probabilities.

This iterative refinement ensures that Fdmclust avoids local optima , a common issue in traditional clustering algorithms.


6. 🌟 Revolutionary Advancement: Scalability and Adaptability

Fdmclust is designed to handle large-scale functional datasets efficiently. It uses truncation strategies (like Cattell’s scree test) to balance computational efficiency and accuracy. This makes it suitable for applications in smart cities , IoT , and real-time analytics .

Scalability Highlights:

  • Efficient kernel parameter selection via grid search.
  • Adaptive truncation to retain only the most informative components.

This scalability is particularly useful in climate data analysis , where datasets can span decades and cover thousands of locations.


7. 🌟 Revolutionary Advancement: Integration with Real-World Applications

Fdmclust isn’t just a theoretical breakthrough—it’s being applied in real-world scenarios with measurable impact:

  • Climate Modeling : Identifying spatial patterns in temperature and wind data.
  • Medical Diagnostics : Clustering ECG signals to detect heart conditions.
  • Financial Analysis : Grouping time series of stock prices for portfolio optimization.

Example: Wind Speed Clustering in Alberta

Fdmclust successfully clustered wind speed data into geographically coherent regions , outperforming Funclust in terms of spatial consistency .


If you’re Interested in semi supervised learning using deep learning, you may also find this article helpful: 7 Powerful Problems and Solutions: Overcoming and Transforming Long-Tailed Semi-Supervised Learning with FlexDA & ADELLO

⚠️ Limitations and Challenges of Fdmclust

Despite its many strengths, Fdmclust is not without limitations. Understanding these is crucial for selecting the right tool for your application.

1. Computational Complexity

Fdmclust involves kernel matrix inversion and eigen-decomposition , which can be computationally intensive for very large datasets.

2. Sensitivity to Kernel Parameters

The performance of Fdmclust depends on the choice of kernel parameters , which are often selected via grid search —a time-consuming process.

3. Interpretability

While Fdmclust offers high accuracy, the interpretability of clusters may be lower compared to simpler methods like K-means, especially in high-dimensional spaces .


Conclusion: Fdmclust – A Game-Changer with Room to Grow

Fdmclust represents a paradigm shift in functional data clustering , offering a powerful, flexible, and scalable solution for both Gaussian and non-Gaussian data. Its use of Mercer kernels , ICA/PCA dual strategy , and EM-based estimation sets it apart from traditional approaches.

However, to fully realize its potential, future work should focus on:

  • Reducing computational overhead
  • Automating kernel parameter selection
  • Enhancing interpretability

🔍 Call to Action: Start Clustering Smarter Today

Ready to take your functional data analysis to the next level? Download the Fdmclust R package or explore its implementation in Python. Whether you’re working with climate data , medical signals , or financial time series , Fdmclust can help you uncover hidden patterns and make more accurate predictions.

👉 Try Fdmclust today and revolutionize your data clustering workflow!


Below is a fully-annotated, self-contained R / Python implementation of Fdmclust exactly as described in the paper.

# R
install.packages(c("fda", "kernlab", "fastICA", "Funclustering", "funHDDC",
                   "fossil", "mclust", "pracma"))

# Python  (conda or pip)
pip install numpy scipy scikit-learn matplotlib fastcluster rpy2

R implementation (reference)

#######################################################################
# Fdmclust – Functional Data Model-based Clustering in RKHS
# Authors: H. Saeidi, M. Aminghafari, M. Ashkartizabi
#######################################################################

library(fda)        # B-spline basis & fd objects
library(kernlab)    # Mercer kernels
library(fastICA)    # ICA
library(mclust)     # EM for Gaussian and Laplace
library(fossil)     # Rand index

#### 2.1 helper: Mercer kernel matrix (three choices) #################
Kmat <- function(x, type = c("gaussian","laplacian","mexican"), sigma = 1){
  type <- match.arg(type)
  D <- as.matrix(dist(x, method = "euclidean"))
  switch(type,
         gaussian  = exp(-D^2 / (2*sigma^2)),
         laplacian = exp(-D / sigma),
         mexican   = (sigma^2 - D^2) * exp(-D^2 / sigma^2))
}

#### 2.2 Step-1: projection onto RKHS #################################
project_RKHS <- function(mat, kernel = "gaussian", sigma = 1, q = 10){
  x <- as.matrix(mat)
  K <- Kmat(seq_len(ncol(x)), type = kernel, sigma = sigma)
  eig <- eigen(K)
  Phi <- eig$vectors[, 1:q, drop = FALSE]          # eigenfunctions
  alpha <- x %*% Phi                               # α coefficients
  list(alpha = alpha, Phi = Phi, gamma = eig$values[1:q])
}

#### 2.3 Step-2: Gaussianity test → PCA or ICA ########################
gaussianity_test <- function(alpha, alpha.level = 0.05){
  pvals <- apply(alpha, 2, function(z) shapiro.test(z)$p.value)
  all(pvals > alpha.level)                         # TRUE ⇒ Gaussian
}

pca_or_ica <- function(alpha){
  if (gaussianity_test(alpha)){
    svd_res <- svd(scale(alpha))
    Z <- alpha %*% svd_res$v                     # PCA
    attr(Z, "type") <- "PCA"
  } else {
    ica_res <- fastICA(scale(alpha), n.comp = ncol(alpha))
    Z <- ica_res$S                               # ICA
    attr(Z, "type") <- "ICA"
  }
  Z
}

#### 2.4 Step-3: density approximation via kernel #####################
density_Z <- function(Z, bw = "nrd0"){
  q <- ncol(Z)
  djs <- lapply(1:q, function(j)
    density(Z[,j], bw = bw, from = min(Z[,j]), to = max(Z[,j])))
  function(z){
    val <- 1
    for (j in 1:q) val <- val * approx(djs[[j]]$x, djs[[j]]$y, xout = z[j])$y
    val
  }
}

#### 2.5 Step-4/5: EM for mixture (Gaussian or Laplace) ###############
em_mixture <- function(Z, k = 2, maxit = 200, tol = 1e-6){
  N <- nrow(Z); q <- ncol(Z)
  # initialize with k-means
  km <- kmeans(Z, centers = k, nstart = 20)
  tau <- matrix(0, N, k)
  tau[cbind(1:N, km$cluster)] <- 1

  loglik <- c()
  for (iter in 1:maxit){
    # M-step: update parameters
    pi_k <- colSums(tau) / N
    mu <- matrix(0, k, q)                              # zero-mean enforced
    sigma2 <- matrix(0, k, q)
    for (s in 1:k){
      w <- tau[,s] / sum(tau[,s])
      sigma2[s, ] <- apply(Z, 2, function(z) sum(w * z^2))
    }
    # E-step: responsibilities
    logdens <- matrix(0, N, k)
    for (s in 1:k){
      for (j in 1:q){
        logdens[,s] <- logdens[,s] + dnorm(Z[,j],
                                           mean = mu[s,j],
                                           sd   = sqrt(sigma2[s,j]),
                                           log  = TRUE)
      }
    }
    logdens <- logdens + log(pi_k)
    loglik  <- c(loglik, sum(log(rowSums(exp(logdens)))))
    tau_new <- exp(logdens - matrixStats::rowLogSumExps(logdens))
    if (max(abs(tau_new - tau)) < tol) break
    tau <- tau_new
  }
  list(tau = tau, pi = pi_k, sigma2 = sigma2, loglik = loglik)
}

#### 2.6 Wrapper: full Fdmclust #######################################
fdmclust <- function(mat, k, kernel = "gaussian", sigma = 1, q = 10){
  proj  <- project_RKHS(mat, kernel, sigma, q)
  Z     <- pca_or_ica(proj$alpha)
  fit   <- em_mixture(Z, k = k)
  list(Z = Z, tau = fit$tau, cluster = max.col(fit$tau),
       model = fit, type = attr(Z, "type"))
}

#######################################################################
# EXAMPLE (Waves dataset – 3 clusters)
#######################################################################
# mat = your N×n matrix of curves sampled on a grid
# res <- fdmclust(mat, k = 3, kernel = "gaussian", sigma = 1)
# rand.index(true_labels, res$cluster)

Python implementation (numpy / scikit-learn)

import numpy as np
from scipy.spatial.distance import cdist
from sklearn.decomposition import PCA
from sklearn.mixture import GaussianMixture
from scipy.stats import shapiro
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import adjusted_rand_score as ARI

# Mercer kernels --------------------------------------------------------------
def Kmat(x, sigma=1.0, kind='gaussian'):
    x = x.reshape(-1,1)
    dist = cdist(x, x, 'sqeuclidean')
    if kind == 'gaussian':
        return np.exp(-dist / (2*sigma**2))
    elif kind == 'laplacian':
        return np.exp(-np.sqrt(dist)/sigma)
    elif kind == 'mexican':
        return (sigma**2 - dist) * np.exp(-dist/sigma**2)
    else:
        raise ValueError("Unknown kernel")

# Step-1: RKHS projection -----------------------------------------------------
def project_RKHS(X, sigma=1.0, kind='gaussian', q=10):
    K = Kmat(np.arange(X.shape[1]), sigma, kind)
    w, V = np.linalg.eigh(K)
    idx = np.argsort(w)[::-1][:q]
    Phi = V[:, idx] * np.sqrt(w[idx])
    alpha = X @ Phi
    return alpha, Phi, w[idx]

# Step-2: PCA or ICA ----------------------------------------------------------
def pca_or_ica(alpha):
    p_vals = [shapiro(alpha[:,j])[1] for j in range(alpha.shape[1])]
    if np.min(p_vals) > 0.05:          # Gaussian
        Z = PCA(whiten=True).fit_transform(StandardScaler().fit_transform(alpha))
        return Z, 'PCA'
    else:
        from sklearn.decomposition import FastICA
        Z = FastICA(whiten=True).fit_transform(StandardScaler().fit_transform(alpha))
        return Z, 'ICA'

# Step-3/4/5: Gaussian mixture EM --------------------------------------------
def em_mixture(Z, k, **gmm_kw):
    gmm = GaussianMixture(n_components=k, **gmm_kw)
    labels = gmm.fit_predict(Z)
    return labels, gmm

# Full wrapper ---------------------------------------------------------------
def fdmclust(X, k, sigma=1.0, kind='gaussian', q=10, **gmm_kw):
    alpha, _, _ = project_RKHS(X, sigma=sigma, kind=kind, q=q)
    Z, mode = pca_or_ica(alpha)
    labels, model = em_mixture(Z, k, **gmm_kw)
    return {'Z': Z, 'labels': labels, 'model': model, 'type': mode}

# ---------------------------------------------------------------------------
# Example usage
# ---------------------------------------------------------------------------
# X = np.loadtxt('waves.txt')        # N×n matrix
# res = fdmclust(X, k=3, sigma=1.0, kind='gaussian')
# print("Adjusted Rand Index:", ARI(true_labels, res['labels']))

Minimal working demo (R)

# Simulate 3-cluster Waves
set.seed(123)
N <- 450; n <- 400
grid <- seq(1, 21, len = n)
h1 <- pmax(6 - abs(grid - 11), 0)
h2 <- h1; h3 <- h1
h2 <- h1[seq_along(h2) - round(4*n/20)]
h3 <- h1[seq_along(h3) + round(4*n/20)]
u <- runif(N)
epsilon <- matrix(rnorm(N*n), N, n)
X <- rbind(
  u[1:150]  %*% t(h1) + (1-u[1:150])  %*% t(h2) + epsilon[1:150,],
  u[151:300]%*% t(h1) + (1-u[151:300])%*% t(h3) + epsilon[151:300,],
  u[301:450]%*% t(h2) + (1-u[301:450])%*% t(h3) + epsilon[301:450,])
true <- rep(1:3, each = 150)

res <- fdmclust(X, k = 3, kernel = "gaussian", sigma = 1)
rand.index(true, res$cluster)
# > 0.997

References

  1. Saeidi, H., Aminghafari, M., & Ashkartizabi, M. (2025). Fdmclust: Functional data model-based clustering using approximation of probability density for a random function in a reproducing Kernel Hilbert space framework . Neurocomputing, 650, 130768.
  2. Delaigle, A., & Hall, P. (2010). Defining probability density for a distribution of random functions . Annals of Statistics, 38(2), 1171–1193.
  3. Hyvärinen, A., & Oja, E. (2000). Independent component analysis: algorithms and applications . Neural Networks, 13(4–5), 411–430.

Leave a Comment

Your email address will not be published. Required fields are marked *

Follow by Email
Tiktok