[moving-average] 개수와 데이터 합계를 유지하지 않고 이동 평균을 계산하는 방법은 무엇입니까?

지금까지받은 수와 총 데이터를 저장하지 않고 이동 누적 평균을 계산하는 방법을 찾으려고합니다.

두 가지 알고리즘을 생각해 냈지만 둘 다 개수를 저장해야합니다.

  • 새 평균 = ((이전 개수 * 이전 데이터) + 다음 데이터) / 다음 개수
  • 새 평균 = 이전 평균 + (다음 데이터-이전 평균) / 다음 개수

이러한 방법의 문제점은 개수가 점점 커져 결과 평균의 정밀도를 잃는다는 것입니다.

첫 번째 방법은 분명히 1로 떨어져있는 이전 개수와 다음 개수를 사용합니다. 이것은 아마도 카운트를 제거하는 방법이 있다고 생각하게했지만 불행히도 아직 찾지 못했습니다. 그래도 조금 더 나아서 두 번째 방법을 얻었지만 여전히 카운트가 존재합니다.

가능합니까, 아니면 불가능한 것을 찾고 있습니까?



답변

간단하게 다음을 수행 할 수 있습니다.

double approxRollingAverage (double avg, double new_sample) {

    avg -= avg / N;
    avg += new_sample / N;

    return avg;
}

N평균화하려는 샘플 수는 어디에 있습니까 ? 이 근사는 지수 이동 평균과 동일합니다. 참조 : C ++에서 롤링 / 이동 평균 계산


답변

New average = old average * (n-1)/n + new value /n

이것은 카운트가 하나의 값만큼만 변경되었다고 가정합니다. M 값으로 변경된 경우 :

new average = old average * (n-len(M))/n + (sum of values in M)/n).

이것은 수학적 공식입니다 (가장 효율적인 공식이라고 생각합니다). 스스로 추가 코드를 작성할 수 있다고 믿습니다.


답변

에서 블로그 평균도 계산됩니다 표본 분산의 계산, 실행에 대한 Welford의 방법 :

여기에 이미지 설명 입력

안타깝게도 SVG 이미지를 업로드 할 수 없습니다.


답변

Muis , Abdullah Al-AgeelFlip 의 답변이 다르게 쓰여진 것을 제외하고 는 모두 수학적으로 동일한 방법에 대한 주석을 제공하는 또 다른 답변 이 있습니다.

물론, 반올림 오류가 각각에 약간 다른 영향을 미치는 방식을 설명하는 José Manuel Ramos 의 분석이 있지만 이는 구현에 따라 다르며 각 답변이 코드에 어떻게 적용되었는지에 따라 변경됩니다.

그러나 다소 큰 차이가 있습니다

그것은 Muis ‘s N, Flip ‘s kAbdullah Al-Ageel ‘s에 n있습니다. 압둘라 알 – Ageel은 매우 무엇인지 설명하지 않습니다 n해야하지만 N하고 k있다는 점에서 차이가 N있다 ” 당신이 평균 이상으로 원하는 샘플 수는 “동안은 k샘플링 값의 수입니다. ( N 샘플 수를 호출 하는 것이 정확한지 의심 스럽지만 )

그리고 여기에서 우리는 아래의 답을 얻습니다. 본질적으로 다른 것들 과 동일한 오래된 지수 가중 이동 평균 이므로 대안을 찾고 있다면 여기에서 중지하십시오.

지수 가중 이동 평균

처음에는 :

average = 0
counter = 0

각 값에 대해 :

counter += 1
average = average + (value - average) / min(counter, FACTOR)

차이점은 min(counter, FACTOR)부분입니다. 이것은 말하는 것과 같습니다 min(Flip's k, Muis's N).

FACTOR평균이 최신 추세를 “따라 잡는”속도에 영향을주는 상수입니다. 숫자가 작을수록 빠릅니다. ( 1더 이상 평균이 아니며 단지 최신 값이됩니다.)

이 대답에는 실행 카운터가 필요합니다 counter. 문제가있는 경우 min(counter, FACTOR)를로 대체하여 Muis 의 대답 FACTOR으로 바꿀 수 있습니다 . 이 작업의 문제는 이동 평균 이 초기화되는 항목의 영향을 받는다는 것입니다. 로 초기화 된 경우 해당 0이 평균을 벗어나는 데 오랜 시간이 걸릴 수 있습니다.average0

어떻게 보이는지

지수 이동 평균


답변

Flip의 대답은 Muis보다 계산적으로 더 일관 적입니다.

이중 숫자 형식을 사용하면 Muis 접근 방식에서 반올림 문제를 볼 수 있습니다.

Muis 접근 방식

나누고 빼면 이전에 저장된 값에 반올림이 나타나 변경됩니다.

그러나 Flip 접근 방식은 저장된 값을 보존하고 분할 수를 줄여서 반올림을 줄이고 저장된 값으로 전파되는 오류를 최소화합니다. 추가 할 항목이있는 경우에만 반올림이 표시됩니다 (N이 크면 추가 할 항목이 없음).

Flip 접근 방식

큰 값의 평균을 만들 때 이러한 변화는 그 평균이 0이되는 경향이 있습니다.

스프레드 시트 프로그램을 사용하여 결과를 보여드립니다.

첫째, 결과는 다음과 같습니다. 결과

A 및 B 열은 각각 n 및 X_n 값입니다.

C 열은 Flip 접근 방식이고 D 열은 Muis 접근 방식이며 그 결과는 평균에 저장됩니다. E 열은 계산에 사용 된 중간 값에 해당합니다.

다음은 짝수 값의 평균을 보여주는 그래프입니다.

그래프

보시다시피 두 접근 방식에는 큰 차이가 있습니다.


답변

비교를 위해 자바 스크립트를 사용하는 예 :

https://jsfiddle.net/drzaus/Lxsa4rpz/

function calcNormalAvg(list) {
    // sum(list) / len(list)
    return list.reduce(function(a, b) { return a + b; }) / list.length;
}
function calcRunningAvg(previousAverage, currentNumber, index) {
    // [ avg' * (n-1) + x ] / n
    return ( previousAverage * (index - 1) + currentNumber ) / index;
}


답변

Java8에서 :

LongSummaryStatistics movingAverage = new LongSummaryStatistics();
movingAverage.accept(new data);
...
average = movingAverage.getAverage();

당신은 또한 가지고 IntSummaryStatistics, DoubleSummaryStatistics