Дисперсия Уэлфорда отличается от дисперсии Numpy

Я хочу использовать метод Уэлфорда для вычисления текущей дисперсии и среднего значения. Я наткнулся на эту реализацию метода Уэлфорда на Python. Однако при тестировании, чтобы перепроверить, что он дает тот же результат, что и стандартная реализация Numpy для расчета дисперсии, я обнаружил, что есть разница в выводе.

Выполнение следующего кода (с использованием unittest модуля Python) показывает, что они дают разные результаты (даже после многократного тестирования):

random_sample = np.random.normal(0, 1, 100)
std = np.var(random_sample, dtype=np.longdouble)
mean = np.mean(random_sample, dtype=np.longdouble)
welford = Welford()
welford.add_all(random_sample)

self.assertAlmostEqual(mean, welford.mean)
self.assertAlmostEqual(var, welford.var_s)

>> AssertionError: 1.1782075496578717837 != 1.1901086360180526 within 7 places (0.011901086360180828804 difference)

Интересно, что существует только разница в дисперсии, а не в среднем.

Для моих целей разница в 0,012 достаточно значительна, чтобы повлиять на мои результаты.

Почему может быть такая разница? Может ли это быть связано с ошибками с плавающей запятой? Если да, то лучше всего было бы переписать пакет, чтобы использовать класс Decimal?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По умолчанию np.var вычисляет так называемую «дисперсию совокупности», в которой количество степеней свободы равно количеству элементов в массиве.

wellford.var_s — выборочная дисперсия, в которой количество степеней свободы равно количеству элементов в массиве минус один.

Чтобы устранить несоответствие, передайте ddof=1 на np.var:

import numpy as np
from welford import Welford
random_sample = np.random.normal(0, 1, 100)
var = np.var(random_sample, dtype=np.longdouble, ddof=1)
welford = Welford()
welford.add_all(random_sample)
np.testing.assert_allclose(var, welford.var_s)

В качестве альтернативы, если в вашем приложении уместно использовать дисперсию генеральной совокупности, используйте welford.var_p.

var = np.var(random_sample, dtype=np.longdouble)
np.testing.assert_allclose(var, welford.var_p)

Описание разницы между ними см. в разрабатываемой версии документации np.var .

Другие вопросы по теме