Overview
Given a correlation matrix generated from $n$ observations, each of which is associated with one or categorical binary or multinomial labels, how can one quantify the (non-)random distribution of each such label across the columns of the matrix or, equivalently, across the leaves of a dendrogram associated with such a matrix?
My goal is to compare several different transformations of some input dataset, and to see which one does a better job capturing the underlying signal in the data, as quantified by the non-random distribution of previously known annotations for each datapoint across a dendrogram or correlation matrix generated from that data?
Intuitively, this is similar to quantifying the non-random distribution of a binary label across data clusters (for which one might use something like Fisher's Exact Test / hypergeometric test), except that I would like to avoid the information loss associated with the discretization that occurs during clustering.
Example:
For example, suppose you have $5 \times 10$ matrix with four related variables, all of which have the same "true" underlying label.
In this case, the goal would be to find a method of comparing alternative correlation matrices / dendrograms generated from this data and choosing the one that results in the most non-random distribution / clustering of the related data points.
set.seed(1)
suppressMessages(library(NMF))
suppressMessages(library(viridis))
# create example data (5 x 10 matrix with 4 correlated columns)
num_rows <- 5
x1 <- abs(rnorm(num_rows) * 10)
dat <- matrix(c(
x1 + rnorm(num_rows),
x1 + rnorm(num_rows),
x1 + rnorm(num_rows),
x1 + rnorm(num_rows),
rnorm(30)), nrow = num_rows)
colnames(dat) <- c(rep('A', 4), rep('B', 6))
cor_mat <- cor(dat)
# high-score (labels grouped together in dendrogram / correlation matrix)
NMF::aheatmap(cor_mat, annCol = list(group = factor(colnames(dat))),
color = viridis(100))
# low-score (labels more randomly-distributed)
fake_cor_mat <- cor_mat + matrix(rnorm(100), nrow = 10)
NMF::aheatmap(fake_cor_mat, annCol = list(group = factor(colnames(dat))),
color = viridis(100))
Created on 2019-10-27 by the reprex package (v0.3.0)
In the above example, a single binary variable is associated with each input data point, but in the more generalized case, each annotation may contain more than two levels. That said, it's not hard to convert the multinomial variables into multiple binary variables via one-hot encoding, so even a solution that only applies to binary labels would work.