运行(一次通过)计算协方差

时间:2016-06-14 10:45:32

标签: statistics covariance

我有一组3d矢量(x,y,z),我想计算协方差矩阵而不存储矢量。

我将在C#中完成,但最终我将在C上在微控制器上实现它,所以我需要算法本身,而不是库。

伪代码也会很棒。

4 个答案:

答案 0 :(得分:5)

如果手头有MatrixVector类,公式很简单:

Vector mean;
Matrix covariance;
for (int i = 0; i < points.size(); ++i) {
  Vector diff = points[i] - mean;
  mean += diff / (i + 1);
  covariance += diff * diff.transpose() * i / (i + 1);
}
covariance *= 1 / points.size()

我个人总是喜欢这种风格,而不是两遍计算。代码很短,结果完美无缺。

MatrixVector可以具有固定的维度,并且可以为此目的轻松编码。您甚至可以将代码重写为离散浮点计算,并避免计算协方差矩阵的对称部分。

请注意,第二行代码中有一个向量外部产品。并非所有的矢量库都能正确解释它。

答案 1 :(得分:1)

我想我找到了解决方案。它基于这篇关于how to calculate covariance manually的文章以及关于calculating running variance的这篇文章。然后我在后者中调整算法来计算协方差而不是方差,这是我从第一篇文章中对它的理解。

angular.element(document).ready(function () {
    angular.bootstrap(document, ['myModule']);
});

答案 2 :(得分:1)

来自emu的代码很优雅,但需要一个额外的步骤才能正确:

Vector mean;
Matrix covariance;
for (int i = 0; i < points.size(); ++i) {
  Vector diff = points[i] - mean;
  mean += diff / (i + 1);
  covariance += diff * diff.transpose() * i / (i + 1);
}

covariance = covariance/(points.size()-1);

注意归一化协方差的最后一步。

答案 3 :(得分:0)

这是R中的一个简单示例,用于说明原理:

a <- matrix(rnorm(22), ncol = 2)
a1 <- a[1:10, ]
a2 <- a[2:11, ]
cov(a1)
cov(a2)
m <- 10

# initial step
m1.1 <- mean(a1[, 1]) 
m1.2 <- mean(a1[, 2]) 

c1.11 <- cov(a1)[1, 1]
c1.22 <- cov(a1)[2, 2]
c1.12 <- cov(a1)[1, 2]


#step 1->2
m2.1 <- m1.1 + (a[11, 1] - a[1, 1])/m
m2.2 <- m1.2 + (a[11, 2] - a[1, 2])/m

c2.11 <- c1.11 + (a[11, 1]^2 - a[1, 1]^2)/(m - 1) + (m1.1^2 - m2.1^2) * m/(m - 1)
c2.22 <- c1.22 + (a[11, 2]^2 - a[1, 2]^2)/(m - 1) + (m1.2^2 - m2.2^2) * m/(m - 1)
c2.12 <- c1.12 + (a[11, 1] * a[11, 2] - a[1, 1]*a[1, 2])/(m - 1) + 
   (m1.1 * m1.2 - m2.1 * m2.2) * m/(m - 1)

cov(a2) - matrix(c(c2.11, c2.12, c2.12, c2.22), ncol=2)