Я пытаюсь найти способ вычислить скользящее кумулятивное среднее без сохранения количества и общих данных, полученных на данный момент.
Я придумал два алгоритма, но оба должны хранить счетчик:
- новое среднее значение = ((старое количество * старые данные) + следующие данные) / следующее количество
- новое среднее = старое среднее + (следующие данные - старое среднее) / следующий счет
Проблема с этими методами заключается в том, что счет становится все больше и больше, что приводит к потере точности получаемого среднего.
Первый метод использует старый счетчик и следующий счет, которые, очевидно, разделены на 1. Это заставило меня подумать, что, возможно, есть способ удалить счетчик, но, к сожалению, я его еще не нашел. Это действительно продвинуло меня немного дальше, в результате появился второй метод, но счетчик все еще присутствует.
Возможно ли это, или я просто ищу невозможное?
moving-average
user1705674
источник
источник
Ответы:
Вы можете просто сделать:
Где
N
количество образцов, по которым вы хотите усреднить. Обратите внимание, что это приближение эквивалентно экспоненциальной скользящей средней. См .: Расчет скользящего / скользящего среднего в C ++источник
5
выборок, среднее значение будет 0,67.avg
инициализации в0
вы получите3.36
через 55
с, а4.46
через 10: cpp.sh/2ryql Для длинных средних это, безусловно, полезное приближение.Предполагается, что счетчик изменился только на одно значение. В случае его изменения на M значения:
Это математическая формула (я считаю, что она наиболее эффективная), полагаю, вы можете делать дальнейший код самостоятельно.
источник
m
новые значения, которые учитываются в новом среднем. Я считаю, чтоsum of new value
здесь подразумевается суммаm
новых значений, используемых для вычисления нового среднего.new_average = (old_average * (n-1) + new_value) / n
- Убирает одну из перегородок.Из блога о выполнении выборочных расчетов дисперсии, где среднее также вычисляется с использованием метода Велфорда :
Жаль, что мы не можем загружать изображения SVG.
источник
Вот еще один ответ предложение комментарии о том , как MUIS , Абдуллы Аль-Ageel и Флип ответ «сек являются все математически то же самое , за исключением того, написаны по- разному.
Конечно, у нас есть Хосе Мануэль Рамос анализ , объясняющий, как ошибки округления влияют на каждую по-своему, но это зависит от реализации и будет меняться в зависимости от того, как каждый ответ был применен к коду.
Однако есть довольно большая разница
Это в MUIS 's
N
, Флип ' sk
, и Абдулла аль-Ageel «sn
. Абдулла Аль-Агил не совсем объясняет, чтоn
должно быть, ноN
иk
отличается в этомN
это « число выборок , где вы хотите , чтобы в среднем за » , аk
является подсчет значений выборки. (Хотя я сомневаюсь в точностиN
определения количества образцов .)И вот мы подходим к ответу ниже. По сути, это та же старая экспоненциально взвешенная скользящая средняя, что и другие, поэтому, если вы искали альтернативу, остановитесь прямо здесь.
Экспоненциально взвешенное скользящее среднее
Первоначально:
Для каждого значения:
Разница в том
min(counter, FACTOR)
. Это то же самое, что сказатьmin(Flip's k, Muis's N)
.FACTOR
- константа, которая влияет на то, как быстро среднее значение «догоняет» последний тренд. Чем меньше число, тем быстрее. (Сейчас1
это уже не среднее значение, а просто последнее значение.)Для этого ответа требуется счетчик хода
counter
. Если проблематично, егоmin(counter, FACTOR)
можно заменить простоFACTOR
, превратив его в ответ Муиса . Проблема с этим заключается в том, что на скользящую среднюю влияют всеaverage
инициализировано. Если он был инициализирован0
, этот ноль может занять много времени, чтобы выйти из среднего значения.Как это в итоге выглядит
источник
max(counter, FACTOR)
.min(counter, FACTOR)
всегда будет возвращать FACTOR, верно?min(counter, FACTOR)
, чтобы учесть период разминки. Без него, если ваш КОЭФФИЦИЕНТ (или N, или желаемое количество образцов) равен 1000, вам понадобится не менее 1000 образцов, прежде чем вы получите точный результат, поскольку все обновления до этого предполагают, что у вас есть 1000 образцов, когда вы можете только есть 20.Ответ Flip в вычислительном отношении более согласован, чем ответ Muis.
Используя формат двойного числа, вы могли увидеть проблему округления в подходе Muis:
Когда вы делите и вычитаете, округление появляется в предыдущем сохраненном значении, изменяя его.
Однако подход Flip сохраняет сохраненное значение и уменьшает количество делений, следовательно, уменьшает округление и минимизирует ошибку, распространяемую на сохраненное значение. Добавление только приведет к округлению, если есть что добавить (когда N большое, добавлять нечего)
Эти изменения замечательны, когда вы стремитесь к нулю среднего значения больших значений.
Я показываю вам результаты с помощью программы для работы с электронными таблицами:
Во-первых, полученные результаты:
Столбцы A и B представляют собой значения n и X_n соответственно.
Столбец C - это подход Flip, а столбец D - подход Muis, результат сохраняется в виде среднего. Столбец E соответствует среднему значению, используемому в вычислениях.
График, показывающий среднее четных значений, является следующим:
Как видите, между обоими подходами есть большие различия.
источник
Пример использования javascript для сравнения:
https://jsfiddle.net/drzaus/Lxsa4rpz/
Показать фрагмент кода
источник
В Java8:
у вас есть также
IntSummaryStatistics
,DoubleSummaryStatistics
...источник
Изящное решение Python, основанное на приведенных выше ответах:
использование:
источник