Я пытаюсь преобразовать код Matlab в numpy и выяснил, что numpy имеет другой результат с функцией std.
в Matlab
std([1,3,4,6])
ans = 2.0817
в тупике
np.std([1,3,4,6])
1.8027756377319946
Это нормально? И как мне с этим справиться?
Я пытаюсь преобразовать код Matlab в numpy и выяснил, что numpy имеет другой результат с функцией std.
в Matlab
std([1,3,4,6])
ans = 2.0817
в тупике
np.std([1,3,4,6])
1.8027756377319946
Это нормально? И как мне с этим справиться?
Ответы:
Функция NumPy np.std
принимает необязательный параметр ddof
: «Дельта степеней свободы». По умолчанию это 0
. Установите его, чтобы 1
получить результат MATLAB:
>>> np.std([1,3,4,6], ddof=1)
2.0816659994661326
Чтобы добавить немного больше контекста, при вычислении дисперсии (стандартное отклонение которой представляет собой квадратный корень) мы обычно делим на количество имеющихся у нас значений.
Но если мы выберем случайную выборку N
элементов из большего распределения и вычислим дисперсию, деление на N
может привести к занижению фактической дисперсии. Чтобы исправить это, мы можем уменьшить число, на которое мы делим ( степени свободы ), до числа меньше N
(обычно N-1
). ddof
Параметр позволяет изменить делитель на величину мы указываем.
Если не указано иное, NumPy вычислит смещенную оценку для дисперсии ( ddof=0
, деления на N
). Это то, что вам нужно, если вы работаете со всем распределением (а не с подмножеством значений, которые были случайно выбраны из более крупного распределения). Если ddof
указан параметр, NumPy N - ddof
вместо этого делит на .
Поведение MATLAB по умолчанию std
- исправить смещение для дисперсии выборки путем деления на N-1
. Это избавляет от некоторой (но, вероятно, не всей) систематической ошибки стандартного отклонения. Вероятно, это именно то, что вам нужно, если вы используете функцию для случайной выборки из большего распределения.
Хороший ответ @hbaderts дает дополнительные математические подробности.
Стандартное отклонение - это квадратный корень из дисперсии. Дисперсия случайной величины X
определяется как
Таким образом, оценка дисперсии будет
где обозначает выборочное среднее. Для случайно выбранных значений можно показать, что эта оценка не сходится к реальной дисперсии, а к
Если вы выбираете выборки случайным образом и оцениваете среднее значение выборки и дисперсию, вам придется использовать скорректированный (несмещенный) оценщик.
который будет сходиться к . Поправочный член также называется поправкой Бесселя.
Теперь по умолчанию MATLABs std
вычисляет несмещенную оценку с поправочным членом n-1
. NumPy однако (как @ajcr объяснено) вычисляет смещенную оценщик без какого - либо поправочного члена по умолчанию. Параметр ddof
позволяет установить любой срок коррекции n-ddof
. Установив его на 1, вы получите тот же результат, что и в MATLAB.
Точно так же MATLAB позволяет добавить второй параметр w
, который определяет «схему взвешивания». Значение по умолчанию, w=0
приводит к поправочному члену n-1
(несмещенная оценка), в то время как для w=1
, только n используется в качестве поправочного члена (смещенная оценка).
n
идти вверху обозначения суммирования, он помещался внутри суммы.
Для людей, которые не разбираются в статистике, упрощенное руководство:
Включите, ddof=1
если вы рассчитываете np.std()
для выборки, взятой из вашего полного набора данных.
Убедитесь ddof=0
, что вы рассчитываете np.std()
для всего населения
DDOF включен для выборок, чтобы уравновесить смещение, которое может возникнуть в числах.
std([1 3 4 6],1)
это эквивалентно NumPy по умолчаниюnp.std([1,3,4,6])
. Все это довольно четко объяснено в документации для Matlab и NumPy, поэтому я настоятельно рекомендую OP обязательно прочитать их в будущем.