【问题标题】:Simple example calculating Mahalanobis distance between two groups in R计算R中两组之间的马氏距离的简单示例
【发布时间】:2017-11-21 22:45:41
【问题描述】:

我正在尝试使用 Excel 重现 this 示例来计算两组之间的马氏距离。

在我看来,这个例子很好地解释了这个概念。但是,我无法在 R 中重现。

示例中使用 Excel 得到的结果是Mahalanobis(g1, g2) = 1.4104

按照为 R 给出的here 的答案并将其应用于上面的数据,如下所示:

# 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)

并对数据执行函数返回以下输出:

$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 结果显着不同。由于我对马氏距离的概念不熟悉,我想知道我是否做错了什么和/或有更好的方法来计算这个,例如使用mahalanobis()?

【问题讨论】:

    标签: r excel mahalanobis


    【解决方案1】:

    你得到不同结果的原因是

    • 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)

    • 您参考的Excel帖子中的最后一个计算步骤不正确,结果应该是1.989278。

    编辑:

    池化协方差矩阵的无偏估计是标准方法,就像在维基百科页面中一样:https://en.wikipedia.org/wiki/Pooled_variance。一个相关的事实是,在 R 中,当您使用 covvar 时,您会得到一个无偏估计器,而不是协方差矩阵的 MLE 估计器。

    编辑2: R 中的 mahalanobis 函数计算从点到分布的 mahalanobis 距离。它不计算两个样本的马氏距离。

    结论:总的来说,计算两个样本之间的马氏距离最标准的方法是原帖中的R代码,它使用了池化协方差矩阵的无偏估计。

    【讨论】:

    • 很好的解释。 cov 中是否有一个参数来处理这个问题,或者应该为它创建一个自定义函数?
    • @Consistency 非常感谢您的回复,绝对有助于阐明这个问题!我尚未将其标记为已接受的答案,因为我有两个问题来回答您的答案: 1. 是否有“正确”/标准的方法来计算汇总协方差矩阵?例如。 mahalanobis() 中使用了什么。例如,在this 帖子中,其计算方式为:((n1/n3)*cov(g1)) + ((n2/n3)*cov(g2))n3=n1+n2。 2.为什么你得到1.989278而不是1.724
    • @Sotos 似乎 R 的 covvar 都给出了协方差的无偏估计(在这种情况下使用 n - 1 作为分母而不是 n),没有理由让它给出 MLE 估计。如果一个人经常使用 MLE 估计,也许应该为它创建一个自定义函数。
    • 是的,我是这么想的。我已经为我构建的异常检测方法实施了 mahalanobis,该方法已实施到商业工具中并且工作正常。不需要 MLE。只是好奇。干杯
    • @raumkundschafter 据我所知,像您的原始 R 代码这样的池化协方差矩阵的无偏估计器是最常用的。如果你想要一个标准的方式,就用这个,虽然你不能说 MLE 是不正确的。
    猜你喜欢
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多