【问题标题】:Compute covariance matrix on our own (without using `cov`)我们自己计算协方差矩阵(不使用`cov`)
【发布时间】:2016-11-03 16:12:21
【问题描述】:

我正在学习有关协方差矩阵的教程,可以在此处找到:http://stats.seandolinar.com/making-a-covariance-matrix-in-r/

它包括以下步骤:

#create a dataframe
a <- c(1,2,3,4,5,6)
b <- c(2,3,5,6,1,9)
c <- c(3,5,5,5,10,8)     
d <- c(10,20,30,40,50,55)
e <- c(7,8,9,4,6,10)

#create matrix from vectors
M <- cbind(a,b,c,d,e)
M_mean <- matrix(data=1, nrow=n) %*% cbind(mean(a),mean(b),mean(c),mean(d),mean(e)) 

k <- ncol(M) #number of variables
n <- nrow(M) #number of subjects

然后像这样创建一个差异矩阵:

D <- M - M_mean

这对我来说非常简单。但下一步这样做是为了创建一个协方差矩阵:

C <- (n-1)^-1 t(D) %*% D

我知道部分 t(D) %% D 除以 (n-1)^1 = 6。但我不知道 t(D) %% D 到底是多少建立起来。

谁能给我解释一下?

【问题讨论】:

    标签: r matrix covariance


    【解决方案1】:

    但我不明白 t(D) %% D 是如何建立的。

    这是矩阵叉积,一种特殊形式的矩阵乘法。如果您不明白它在做什么,请考虑使用以下 R 循环来帮助您理解这一点:

    DtD <- matrix(0, nrow = ncol(D), ncol = ncol(D))
    for (j in 1:ncol(D)) 
      for (i in 1:ncol(D))
        DtD[i, j] <- sum(D[, i] * D[, j])
    

    注意,实际上没有人会为此编写 R 循环;这只是为了帮助您理解算法。


    原答案

    假设我们有一个矩阵X,其中每一列给出特定随机变量的观察值,通常我们只使用R基函数cov(X)来得到协方差矩阵。

    现在你想自己写一个协方差函数;这也不难(我很久以前就做过这个练习)。它需要 3 个步骤:

    • 列居中(即所有变量的去均值);
    • 矩阵叉积;
    • 平均(超过nrow(X) - 1 而不是nrow(X) 用于偏差调整)。

    这个短代码可以做到:

    crossprod(sweep(X, 2L, colMeans(X))) / (nrow(X) - 1L)
    

    考虑一个小例子

    set.seed(0)
    ## 3 variable, each with 10 observations
    X <- matrix(rnorm(30), nrow = 10, ncol = 3)
    
    ## reference computation by `cov`
    cov(X)
    #           [,1]        [,2]        [,3]
    #[1,]  1.4528358 -0.20093966 -0.10432388
    #[2,] -0.2009397  0.46086672 -0.05828058
    #[3,] -0.1043239 -0.05828058  0.48606879
    
    ## own implementation
    crossprod(sweep(X, 2L, colMeans(X))) / (nrow(X) - 1L)
    #           [,1]        [,2]        [,3]
    #[1,]  1.4528358 -0.20093966 -0.10432388
    #[2,] -0.2009397  0.46086672 -0.05828058
    #[3,] -0.1043239 -0.05828058  0.48606879
    

    如果要获取相关矩阵怎么办?

    有很多方法。如果我们想直接得到它,这样做:

    crossprod(scale(X)) / (nrow(X) - 1L)
    #           [,1]       [,2]       [,3]
    #[1,]  1.0000000 -0.2455668 -0.1241443
    #[2,] -0.2455668  1.0000000 -0.1231367
    #[3,] -0.1241443 -0.1231367  1.0000000
    

    如果我们想首先获得协方差,然后(对称地)通过根对角线重新缩放它以获得相关性,我们可以这样做:

    ## covariance first
    V <- crossprod(sweep(X, 2L, colMeans(X))) / (nrow(X) - 1L)
    
    ## symmetric rescaling
    V / tcrossprod(diag(V) ^ 0.5)
    #           [,1]       [,2]       [,3]
    #[1,]  1.0000000 -0.2455668 -0.1241443
    #[2,] -0.2455668  1.0000000 -0.1231367
    #[3,] -0.1241443 -0.1231367  1.0000000
    

    我们还可以使用服务 R 函数cov2cor 将协方差转换为相关性:

    cov2cor(V)
    #           [,1]       [,2]       [,3]
    #[1,]  1.0000000 -0.2455668 -0.1241443
    #[2,] -0.2455668  1.0000000 -0.1231367
    #[3,] -0.1241443 -0.1231367  1.0000000
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-13
      • 1970-01-01
      • 2018-08-25
      • 2011-11-25
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多