--- title: "Clusters of effects curves and waveforms with clustEff" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Clusters of effects curves and waveforms with clustEff} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4) ``` ```{r setup} library(clustEff) ``` ## 1. The dissimilarity Sottile and Adelfio (2019) proposed a dissimilarity between curves $\beta_1(p), \dots, \beta_q(p)$ evaluated on a common grid that combines * their **shape**: $d_{shape}(p) = I\{sign(\beta_i''(p)) = sign(\beta_{i'}''(p))\}$, the concordance of convexity; * their **closeness**: $d_{distance}(p) = I\{|\beta_i(p) - \beta_{i'}(p)| \le f_\alpha(p)\}$, where $f_\alpha(p)$ is the $\alpha$-quantile of the distances between all pairs of curves at $p$; as $d(i, i') = 1 - \int d_{shape}(p)\, d_{distance}(p)\,dp$. The dissimilarity is computed by `distshape()` and used by `clustEff()` for hierarchical clustering. ## 2. Waveforms We simulate 16 noisy waveforms from three shapes, as in Section 4.2 of the paper, with a noise variance that changes over time. ```{r waves} set.seed(1234) tt <- seq(0, 1, length.out = 200) sdt <- 0.3 * sqrt(pmax(4 * pmax(tt - 0.2, 0) - 8 * pmax(tt - 0.5, 0) + 4 * pmax(tt - 0.8, 0), 0)) W <- cbind(sapply(1:6, function(i) sin(3 * pi * tt) + rnorm(200, 0, sdt)), sapply(1:6, function(i) cos(3 * pi * tt) + rnorm(200, 0, sdt)), sapply(1:4, function(i) sin(3 * pi * tt) * cos(pi * tt) + rnorm(200, 0, sdt))) ``` The shape component uses second derivatives, so noisy curves are smoothed first (`smooth = TRUE`, smoothing splines). With waveforms the default $\alpha$ is 0.5. ```{r waves-fit} fit <- clustEff(W, p = tt, k = c(2, 6), smooth = TRUE) fit summary(fit) ``` ```{r waves-plot, fig.height = 7} oldpar <- par(mfrow = c(2, 2)) plot(fit, "dendrogram") plot(fit, "clusters") plot(fit, "silhouette") plot(fit, "criterion") par(oldpar) ``` ## 3. Effects curves of quantile regression coefficients models In quantile regression coefficients modeling (QRCM, Frumento and Bottai, 2016; package 'qrcm') each coefficient is a parametric function of the quantile order, $\beta_j(p \mid \theta) = \theta_j^\top b(p)$. `extract_curves()` extracts the effects curves, their pointwise confidence bands and their second derivatives (computed from the fitted coefficient functions) from one or more `qrcm::iqr()` fits. Following the multivariate example of the paper, we fit one model for each of 9 responses and cluster the effects of the covariate `x`, which belong to three groups. ```{r qrcm, eval = requireNamespace("qrcm", quietly = TRUE)} set.seed(1) n <- 500 x <- runif(n, 0, 5) slope <- list(function(u) 0.5 + 0.5 * u + u^2, function(u) -0.5 + 0.5 * u + u^2, function(u) 0.3 - 0.5 * u - u^2 + 2 * u^3) fits <- lapply(1:9, function(r) { u <- runif(n) y <- 1 + qnorm(u) + slope[[(r - 1) %/% 3 + 1]](u) * x qrcm::iqr(y ~ x, formula.p = ~ I(p) + I(p^2) + I(p^3)) }) names(fits) <- paste0("y", 1:9) ec <- extract_curves(fits, which = "x") ec fit2 <- clustEff(ec, k = 3) summary(fit2) oldpar <- par(mfrow = c(1, 2)) plot(fit2, "dendrogram") plot(fit2, "clusters") par(oldpar) ``` With confidence bands the default $\alpha$ is 0.25: two curves are *close* at $p$ if their distance is among the 25% smallest distances between pairs of curves. With 9 curves in three groups of three, the pairs within groups are exactly 25% of all pairs, so $\alpha$ should not be smaller than this proportion. Here the number of clusters is fixed after inspecting the dendrogram; with only nine noisy estimated curves the automatic criteria are less reliable. `fit2$signif` indicates, for each cluster, where its mean band excludes zero. ## 4. Choosing the number of clusters When `k` is a range, `criterion` selects the number of clusters: * `"height"` (default): the largest gap between consecutive heights of the dendrogram; * `"pi.out"`: average proportion of curves outside the mean bands of their cluster (Sottile and Adelfio, 2019, Section 3.1), elbow rule; * `"dist.rel"`: $l\,\max_j$ of the mean $L_1$ distance from the cluster mean (Section 3.1), first number of clusters at which it stops decreasing; * `"silhouette"`: average silhouette width (default of 'clustEff' 0.3.x). A small simulation with two to four groups of polynomial effects curves gives an idea of their behaviour (proportion of replicates in which the true number of groups is selected): ```{r sim} p <- seq(0.01, 0.99, 0.01) th <- list(c(.5, .5, 1, 2), c(-3, .5, 1, .5), c(.3, -.5, -1, 2), c(2.5, .5, 1, 2)) crits <- c("height", "pi.out", "dist.rel", "silhouette") set.seed(3) res <- t(sapply(1:12, function(r) { G <- 2 + r %% 3 B <- do.call(cbind, lapply(1:G, function(g) sapply(1:8, function(i) { t <- th[[g]] + rnorm(4, 0, 0.3); t[1] + t[2] * p + t[3] * p^2 + t[4] * p^3 }))) sapply(crits, function(cr) clustEff(B, B - 0.6, B + 0.6, p = p, k = c(2, 7), criterion = cr)$k == G) })) colMeans(res) ``` ## 5. FPCAC The FPCAC algorithm of Adelfio et al. (2011) represents the curves on a B-spline basis, computes their functional principal component scores and applies a trimmed k-means to the scores; the trimmed curves (cluster 0) are potential outliers. ```{r fpcac} W2 <- cbind(W[, 1:12], sapply(1:2, function(i) rnorm(200, 0, 0.3))) # two outliers set.seed(1) o <- opt.fpcac(W2, t = tt, k.max = 5, nbasis = 12, alpha = 0.15) o f <- fpcac(W2, t = tt, K = o$K.opt, nbasis = 12, alpha = 0.15) f plot(f) ``` ## References * Adelfio, G., Chiodi, M., D'Alessandro, A. and Luzio, D. (2011). FPCA algorithm for waveform clustering. *Journal of Communication and Computer*, 8, 494-502. * Frumento, P. and Bottai, M. (2016). Parametric modeling of quantile regression coefficient functions. *Biometrics*, 72(1), 74-84. * Sottile, G. and Adelfio, G. (2019). Clusters of effects curves in quantile regression models. *Computational Statistics*, 34, 551-569.