Поскольку абсолютное отклонение между 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
Это для случая среднего абсолютного отклонения.Обычно используется безумный (медиана абсолютного отклонения), который невозможно программировать рекурсивно.но среднее абсолютное отклонение также полезно в большинстве случаев.Когда мы говорим о сотнях значений из распределений, близких к нормальным, оба значения очень близки.
Если вы просто хотите получить сумму абсолютных отклонений, жизнь станет еще проще: просто верните 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"))