计算 R 中两组之间马氏距离的简单示例
Simple example calculating Mahalanobis distance between two groups in R
我正在尝试使用 Excel 重现 this 示例来计算两组之间的马氏距离。
在我看来,这个例子很好地解释了这个概念。但是,我无法在 R 中重现。
例子中使用Excel得到的结果是Mahalanobis(g1, g2) = 1.4104
.
根据 R 给出的 答案并将其应用于上述数据,如下所示:
# dataset used in the Excel example
g1 <- matrix(c(2, 2, 2, 5, 6, 5, 7, 3, 4, 7, 6, 4, 5, 3, 4, 6, 2, 5, 1, 3), ncol = 2, byrow = TRUE)
g2 <- matrix(c(6, 5, 7, 4, 8, 7, 5, 6, 5, 4), ncol = 2, byrow = TRUE)
# function adopted from R example
D.sq <- function (g1, g2) {
dbar <- as.vector(colMeans(g1) - colMeans(g2))
S1 <- cov(g1)
S2 <- cov(g2)
n1 <- nrow(g1)
n2 <- nrow(g2)
V <- as.matrix((1/(n1 + n2 - 2)) * (((n1 - 1) * S1) + ((n2 - 1) * S2)))
D.sq <- t(dbar) %*% solve(V) %*% dbar
res <- list()
res$D.sq <- D.sq
res$V <- V
res
}
D.sq(g1,g2)
并对数据执行函数 returns 以下输出:
$D.sq
[,1]
[1,] 1.724041
$V
[,1] [,2]
[1,] 3.5153846 0.3153846
[2,] 0.3153846 2.2230769
Afaik $D.sq
表示距离,1.724
与 Excel 示例的 1.4101
结果明显不同。由于我是马氏距离概念的新手,我想知道我是否做错了什么 and/or 有更好的方法来计算这个,例如使用 mahalanobis()?
你得到不同结果的原因是
Excel 算法实际上与 R 算法的不同之处在于计算合并协方差矩阵的方式,R 版本为您提供协方差矩阵的无偏估计结果,而 Excel 版本为您提供 MLE 估计。在 R 版本中,您可以像这样计算矩阵:((n1 - 1) * cov(g1) + (n2 - 1) * cov(g2)) / (n1 + n2 - 2)
;而在 Excel 版本中:((n1 - 1) * cov(g1) + (n2 - 1) * cov(g2)) / (n1 + n2)
.
您所指的Excelpost中的最后一个计算步骤不正确,结果应该是1.989278。
编辑:
合并协方差矩阵的无偏估计是标准方法,如维基百科页面中所述:https://en.wikipedia.org/wiki/Pooled_variance。一个相关的事实是,在 R 中,当您使用 cov
或 var
时,您会得到一个无偏估计量而不是协方差矩阵的 MLE 估计量。
编辑2:
R 中的 mahalanobis 函数计算从点到分布的 mahalanobis 距离。不计算两个样本的马哈拉诺比斯距离
结论:综上所述,最标准的计算两个样本间马哈拉诺比斯距离的方法是原始post中的R代码,它使用了合并协方差矩阵的无偏估计
我正在尝试使用 Excel 重现 this 示例来计算两组之间的马氏距离。
在我看来,这个例子很好地解释了这个概念。但是,我无法在 R 中重现。
例子中使用Excel得到的结果是Mahalanobis(g1, g2) = 1.4104
.
根据 R 给出的
# dataset used in the Excel example
g1 <- matrix(c(2, 2, 2, 5, 6, 5, 7, 3, 4, 7, 6, 4, 5, 3, 4, 6, 2, 5, 1, 3), ncol = 2, byrow = TRUE)
g2 <- matrix(c(6, 5, 7, 4, 8, 7, 5, 6, 5, 4), ncol = 2, byrow = TRUE)
# function adopted from R example
D.sq <- function (g1, g2) {
dbar <- as.vector(colMeans(g1) - colMeans(g2))
S1 <- cov(g1)
S2 <- cov(g2)
n1 <- nrow(g1)
n2 <- nrow(g2)
V <- as.matrix((1/(n1 + n2 - 2)) * (((n1 - 1) * S1) + ((n2 - 1) * S2)))
D.sq <- t(dbar) %*% solve(V) %*% dbar
res <- list()
res$D.sq <- D.sq
res$V <- V
res
}
D.sq(g1,g2)
并对数据执行函数 returns 以下输出:
$D.sq
[,1]
[1,] 1.724041
$V
[,1] [,2]
[1,] 3.5153846 0.3153846
[2,] 0.3153846 2.2230769
Afaik $D.sq
表示距离,1.724
与 Excel 示例的 1.4101
结果明显不同。由于我是马氏距离概念的新手,我想知道我是否做错了什么 and/or 有更好的方法来计算这个,例如使用 mahalanobis()?
你得到不同结果的原因是
Excel 算法实际上与 R 算法的不同之处在于计算合并协方差矩阵的方式,R 版本为您提供协方差矩阵的无偏估计结果,而 Excel 版本为您提供 MLE 估计。在 R 版本中,您可以像这样计算矩阵:
((n1 - 1) * cov(g1) + (n2 - 1) * cov(g2)) / (n1 + n2 - 2)
;而在 Excel 版本中:((n1 - 1) * cov(g1) + (n2 - 1) * cov(g2)) / (n1 + n2)
.您所指的Excelpost中的最后一个计算步骤不正确,结果应该是1.989278。
编辑:
合并协方差矩阵的无偏估计是标准方法,如维基百科页面中所述:https://en.wikipedia.org/wiki/Pooled_variance。一个相关的事实是,在 R 中,当您使用 cov
或 var
时,您会得到一个无偏估计量而不是协方差矩阵的 MLE 估计量。
编辑2: R 中的 mahalanobis 函数计算从点到分布的 mahalanobis 距离。不计算两个样本的马哈拉诺比斯距离
结论:综上所述,最标准的计算两个样本间马哈拉诺比斯距离的方法是原始post中的R代码,它使用了合并协方差矩阵的无偏估计