r - 自己计算协方差矩阵(不使用 `cov` )

标签 r matrix covariance

我正在关注有关协方差矩阵的教程,可以在这里找到: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 到底是多少建立起来。

谁能给我解释一下吗?

最佳答案

But I do not get how exactly t(D) %% D is built up.

这是矩阵叉积,矩阵乘法的一种特殊形式。如果您不明白它在做什么,请考虑以下 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

关于r - 自己计算协方差矩阵(不使用 `cov` ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40406382/

相关文章:

r - 如何以整洁的方式重新排序因子水平?

C - 矩阵上错误的打印值

python - 如何将两个列表中的所有值相乘并获得相应的矩阵

matrix - 尝试对两个乘积求和时出错,其中一个乘积是 1x2 矩阵

c# - 如何将苹果委托(delegate)添加到水果委托(delegate)列表中?

R:按日期排序(按年、按月)

r - 如何将对数图的值从指数表示法更改为点阵包中的数值?

css - 是否可以在 Rvest 中获取 CSS 样式值?

python - 您可以在 Python 类型注释中指定方差吗?

c# - 如何在 C# 中使用类的类型作为继承的集合属性的类型参数