r - 每对观测值的马氏距离

标签 r matrix distance mahalanobis

我正在尝试计算数据集 dat 的每个观测值之间的马哈拉诺比斯距离,其中每一行都是一个观测值,每一列都是一个变量。该距离定义为:

formula

我写了一个函数来做到这一点,但我觉得它很慢。在 R 中是否有更好的方法来计算这个值?

生成一些数据来测试功能:

generateData <- function(nObs, nVar){
  library(MASS)
  mvrnorm(n=nObs, rep(0,nVar), diag(nVar))
  }

这是我到目前为止编写的函数。它们都有效,对于我的数据(800 个观测值和 90 个变量),method = "forLoop"method = "apply" 大约需要 30 和 33 秒,分别。

mhbd_calc2 <- function(dat, method) { #Method is either "forLoop" or "apply"
  dat <- as.matrix(na.omit(dat))
  nObs <- nrow(dat)
  mhbd <- matrix(nrow=nObs,ncol = nObs)
  cv_mat_inv = solve(var(dat))

  distMH = function(x){  #Mahalanobis distance function
    diff = dat[x[1],]-dat[x[2],]
    diff %*% cv_mat_inv %*% diff
  }

  if(method=="forLoop")
  {
    for (i in 1:nObs){
      for(j in 1:i){
        mhbd[i,j] <- distMH(c(i,j))
      }
    }
  }
  if(method=="apply")
  {
    mhbd[lower.tri(mhbd)] = apply(combn(nrow(dat),2),2, distMH)
  }
  result = sqrt(mhbd)
  colnames(result)=rownames(dat)
  rownames(result)=rownames(dat)
  return(as.dist(result))
}

注意:我尝试使用 outer() 但它甚至更慢(60 秒)

最佳答案

您需要一些数学知识。

  1. 对经验协方差进行 Cholesky 因式分解,然后标准化您的观察结果;
  2. 使用 dist 计算变换后的观测值的欧氏距离。

dist.maha <- function (dat) {
  X <- as.matrix(na.omit(dat))  ## ensure a valid matrix
  V <- cov(X)  ## empirical covariance; positive definite
  L <- t(chol(V))  ## lower triangular factor
  stdX <- t(forwardsolve(L, t(X)))  ## standardization
  dist(stdX)  ## use `dist`
  }

示例

set.seed(0)
x <- matrix(rnorm(6 * 3), 6, 3)

dist.maha(x)
#         1        2        3        4        5
#2 2.362109                                    
#3 1.725084 1.495655                           
#4 2.959946 2.715641 2.690788                  
#5 3.044610 1.218184 1.531026 2.717390         
#6 2.740958 1.694767 2.877993 2.978265 2.794879

结果与您的 mhbd_calc2 一致。

关于r - 每对观测值的马氏距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41025674/

相关文章:

r - formatDistData(),距离必须为数字

Android ARCore 测量距离

parameters - Scikit-learn:我们如何定义网格搜索的距离度量参数

r - 为每组添加缺失值的行

r - shiny/ggplot2 中的可变绘图大小

r - R 中的高效矩阵运算

arrays - 如何在 Julia 中乘以多维数组/矩阵

在 R 的数据框中重命名和重新编码新变量的范围

r - 如何知道随机森林生成的回归模型好不好? (MSE 和 %Var(y))

android - 当我需要使用 scaleType 矩阵时如何在 onCreate 中将图像缩放到 imageview