Чому numpy std () дає інший результат для matlab std ()?


87

Я намагаюся перетворити код matlab в numpy і зрозумів, що numpy має інший результат за допомогою функції std.

у матлабі

std([1,3,4,6])
ans =  2.0817

в numpy

np.std([1,3,4,6])
1.8027756377319946

Це нормально? І як мені з цим впоратися?

Відповіді:


145

Функція 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 дає подальші математичні подробиці.


4
Додам, що в Matlab std([1 3 4 6],1)це еквівалентно за замовчуванням NumPy np.std([1,3,4,6]). Все це досить чітко пояснено в документації для Matlab та NumPy, тому я настійно рекомендую OP обов'язково прочитати їх у майбутньому.
horchler

У якийсь момент цей стандарт змінився: np.std () = np.std (ddof = 1), хоча в документації сказано, що np.std () має за замовчуванням ddof = 0 ...
ColinMac

61

Стандартне відхилення - це квадратний корінь з дисперсії. Дисперсія випадкової величини Xвизначається як

визначення дисперсії

Оцінювач дисперсії буде таким чином

упереджений оцінювач

де середнє значення вибіркипозначає середнє значення вибірки. Для випадково вибраних xiможна показати, що цей оцінювач сходиться не до реальної дисперсії, а до

неупереджений оцінювач

Якщо ви вибрали випадковим чином вибірки та оцінили середнє значення та дисперсію вибірки, вам доведеться використовувати виправлений (неупереджений) оцінювач

неупереджений оцінювач

яка сходиться до сигма в квадраті. Термін корекції n-1також називають корекцією Бесселя.

Тепер за замовчуванням MATLABs stdобчислює неупереджений оцінювач із терміном корекції n-1. Однак NumPy (як пояснив @ajcr) обчислює упереджений кошторисник без затримки за замовчуванням. Параметр ddofдозволяє встановити будь-який термін виправлення n-ddof. Встановивши значення 1, ви отримуєте той самий результат, що і в MATLAB.

Подібним чином MATLAB дозволяє додавати другий параметр w, який визначає "схему зважування". Значення за замовчуванням, w=0призводить до виправлення терміну n-1(неупереджений оцінювач), тоді як для w=1, лише n використовується як термін виправлення (зміщений оцінювач).


2
У формулі виправленої оцінки коефіцієнт n (у межах суми) не повинен бути присутнім.
Frunobulax

3
Інтуїція терміну n-1 у дисперсії: ви вже використовували свої зразки для оцінки середнього значення, яке ви будете використовувати для апроксимації дисперсії. Це вводить кореляцію, і, отже, ddof має бути 1.
Маттіас

@Frunobulax Я виправив помилку для нащадків. У вихідному рівнянні сталося те, що верхня межа суми відображалася неправильно. Замість того, nщоб знаходитись у верхній частині нотації підсумовування, вона входила всередину суми.
rayryeng

4

Для людей, які не чудові зі статистикою, спрощений посібник:

  • Включіть, ddof=1якщо ви розраховуєте np.std()для вибірки, взятої з вашого повного набору даних.

  • Переконайтеся, ddof=0що ви розраховуєте np.std()для повної сукупності

DDOF включений для зразків, щоб урівноважити зміщення, яке може мати місце у числах.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.