在线算法计算绝对偏差

fma*_*ark 11 language-agnostic algorithm math statistics

我试图在线计算向量的绝对偏差,也就是说,在接收向量中的每个项目时,不使用整个向量.绝对偏差是向量中每个项目与均值之间的绝对差值的总和:

\ sum_ {I = 0} ^ {N  -  1} {{ABS%28 \划线{X}%20-%20x_i}%29}

我知道矢量的方差可以用这种方式计算.方差类似于绝对偏差,但每个差异是平方的:

\压裂{\ sum_ {I = 0} ^ {N  -  1} {{%28 \划线{X}%20-%20x_i}%29} ^ 2} {N}

方差的在线算法如下:

n = 0
mean = 0
M2 = 0

def calculate_online_variance(x):
    n = n + 1
    delta = x - mean
    mean = mean + delta/n
    M2 = M2 + delta*(x - mean)  # This expression uses the new value of mean
    variance_n = M2/n
    return variance_n
Run Code Online (Sandbox Code Playgroud)

是否有这样的算法来计算绝对偏差?我自己不能制定一个递归定义,但更聪明的头可能会占上风!

Jor*_*eys 5

由于x和均值之间的绝对偏差可以定义为平方差的平方根,如果您对一致但有偏差的估计(意味着无穷大的极限是预期值)感到满意,则自适应是微不足道的:

n = 0
mean = 0
M2 = 0

def calculate_online_avg_abs_dev(x):
    n = n + 1
    delta = x - mean
    mean = mean + delta/n
    M2 = M2 + sqrt(delta*(x - mean))  
    avg_abs_dev_n = M2/n 
Run Code Online (Sandbox Code Playgroud)

这是针对平均绝对偏差的情况.通常使用mad(中位数绝对偏差),这是不可能递归编程的.但在大多数情况下,平均绝对偏差是有用的.当我们谈论接近正态分布的数百个值时,两个值都非常接近.

如果你只想要绝对偏差的总和,生活就更简单了:只需返回M2.

请注意这样一个事实,即您给出的算法和对绝对偏差的微不足道的适应性略有偏差.

R中的模拟证明算法以这种方式工作:

替代文字

红线是真值,黑线是遵循上述算法的渐进值.

代码:

calculate_online_abs_dev <- function(x,n){
  M2=0
  mean=0
  out <- numeric(n)
  for(i in 1:n) {
      delta <- x[i] - mean
      mean <- mean + delta/i
      M2 = M2 + sqrt(delta*(x[i] - mean))
      out[i] <- M2/i

  }
  return(out)
}

set.seed(2010)
x <- rnorm(100)

Abs_Dev <- calculate_online_abs_dev(x,length(x))
True_Val <- sapply(1:length(x),function(i)sum(abs(x[1:i]-mean(x[1:i])))/i)

plot(1:length(x),Abs_Dev,type="l",xlab="number of values",lwd=2)
lines(1:length(x),True_Val,col="red",lty=2,lwd=2)
legend("bottomright",lty=c(1,2),col=c("black","red"),
  legend=c("Online Calc","True Value"))
Run Code Online (Sandbox Code Playgroud)


Bet*_*eta 1

我认为这是不可能的。

在方差公式中,可以将 x 和 x 2项分开,这样就足以跟踪这些总和(和 n)。在绝对偏差的公式中这是不可能的。

我认为最好的办法(除了保留整个向量并根据需要计算绝对偏差)是保留一个排序的元素列表。对于每个新元素,这是 O(log(n)),但是添加元素后,重新计算绝对偏差的成本是 O(log(n))。这可能值得也可能不值得,具体取决于您的应用程序。