Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 每对观测值的马氏距离_R_Matrix_Distance_Mahalanobis - Fatal编程技术网

R 每对观测值的马氏距离

R 每对观测值的马氏距离,r,matrix,distance,mahalanobis,R,Matrix,Distance,Mahalanobis,我试图计算数据集dat的每个观测值之间的马氏距离,其中每行是一个观测值,每列是一个变量。该距离定义为: 我写了一个函数来实现它,但我觉得它很慢。有没有更好的方法来计算R 要生成一些数据以测试函数,请执行以下操作: generateData <- function(nObs, nVar){ library(MASS) mvrnorm(n=nObs, rep(0,nVar), diag(nVar)) } 注意:我试着使用outer(),但速度更慢(60秒)你需要一些数学知识 对

我试图计算数据集
dat
的每个观测值之间的马氏距离,其中每行是一个观测值,每列是一个变量。该距离定义为:

我写了一个函数来实现它,但我觉得它很慢。有没有更好的方法来计算R

要生成一些数据以测试函数,请执行以下操作:

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

注意:我试着使用
outer()
,但速度更慢(60秒)

你需要一些数学知识

  • 对经验协方差进行Cholesky分解,然后将观察值标准化
  • 使用
    dist
    计算变换观测值的欧几里德距离


  • dist.maha所以,如果我理解正确的话,您的dist.maha稍微不那么精确,但要快得多?对于7位数的精度,这与我的testsI是一样的,可能是错误的,但choleski方法无法验证矩阵是否接近奇异。如果是这样的话,它可能会给出我们不想要的高值,不是吗?而solve()执行此验证并返回一个错误来防止它。我认为这超出了我的知识范围,但我肯定会四处询问。另外,如果你不介意的话,你能详细说明一下你的方法是如何工作的吗?这个函数肯定会为我节省大量时间,非常感谢:)您好,我尝试使用Optmatch包中的match_on函数交叉验证这个解决方案(默认值是计算成对Malahanobis距离),我得到了不同的结果。你知道为什么会这样吗?
    
    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))
    }
    
    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