I need to perform a Jeffries-Matusita distance analysis for spectral separability in R. I am working on Arcgis and I would like to know which classes' statistics (mean, sd, covariance matrix) are used in JMdist function. I've been trying, but I keep obtaining only NA's in the vector which is supposed to present the JM distances of all the class combinations, and I believe that it is because I am not using the right information to run the function.
-
Please have a look at [How to make a great R reproducible example ](https://stackoverflow.com/a/5963610/11932936). In particular, you are unlikely to receive help if you don't share any data and code with which you encountered your problem. – shs Feb 10 '23 at 12:44
-
Please provide enough code so others can better understand or reproduce the problem. – Community Feb 14 '23 at 14:16
1 Answers
The Jeffries-Matusita (JM) distance measures the separability between a pair of probability distributions using the Bhattacharyya index. In remote sensing problems the JM distance is often used to measure the spectral separability between two groups (e.g. two Land Use / Land Conver classes). Therefore, the variables to be evaluated are the spectral bands. So you can get the spectral band which maximizes the spectral separability between two classes.
An important issue about the JM distance is that there are two versions of the JM distance.
The original JM distance is defined as:
JMd_ij =√2(1-e^(-B_ij))
where B_ij is the Bhattacharyya "distance" between the distribution i and the distribution j. Therefore the JM distance can take values in the range [0, √2].
However, various remote sensing manuals and software packages such as SCP-Qgis use the following equation:
JMd_ij =2(1-e^(-B_ij))
For example the manual by Richards & Jia (2006) uses this version. According to this equation, the JM distance can take values in the range [0, 2]. This difference is important since applying the square root makes separability values > 1 smaller, and values < 1 larger.
It is therefore important that you define which version of the JM distance you are using to report your results. Especially if you want to compare your results with those of other studies.
The varSel
package uses JMd_ij =√ 2(1-e^(-Bij))
as can be seen in its source code: View(JMdist)
.
You can modify the code to use the Richards & Jia (2006) equation as I show:
JMdist_Richards_Jia_2006 <- function (g, X)
{
# Jeffries-Matusita Distance used in Richards & Jia (2006).
# JM_ij = = √ 2(1-e^(-B_ij))
# where B_ij is the Bhattacharyya "distance" between i and j.
# Source:
## https://link.springer.com/book/10.1007/978-3-642-30062-2
X <- as.matrix(X)
nfeat <- ncol(X)
nclass <- length(unique(g))
mu <- by(X, g, colMeans)
Cov <- by(X, g, stats::cov)
ncomb <- t(utils::combn(unique(g), 2))
Bhat <- c()
jm <- c()
for (j in 1:nrow(ncomb)) {
mu.i <- mu[[ncomb[j, 1]]]
cov.i <- Cov[[ncomb[j, 1]]]
mu.j <- mu[[ncomb[j, 2]]]
cov.j <- Cov[[ncomb[j, 2]]]
if (nfeat == 1) {
Bhat[j] <- (1/8) * t(mu.i - mu.j) %*% (solve((cov.i +
cov.j)/2)) %*% (mu.i - mu.j) + 0.5 * log((((cov.i +
cov.j)/2))/(sqrt(((cov.i)) * ((cov.j)))), base = exp(1))
}
else {
Bhat[j] <- (1/8) * t(mu.i - mu.j) %*% (solve((cov.i +
cov.j)/2)) %*% (mu.i - mu.j) + 0.5 * log(det(((cov.i +
cov.j)/2))/(sqrt((det(cov.i)) * (det(cov.j)))),
base = exp(1))
}
jm[j] <- 2 * (1 - exp(-Bhat[j]))
}
return(list(classComb = ncomb, jmdist = jm))
}
Finally, as you can see in the source code JMdist
computes the covariance matrix using the cov()
R function.

- 254
- 1
- 11