Mengapa numpy std () memberikan hasil yang berbeda dengan matlab std ()?


88

Saya mencoba mengubah kode matlab menjadi numpy dan menemukan bahwa numpy memiliki hasil yang berbeda dengan fungsi std.

di matlab

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

di numpy

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

Apakah ini normal? Dan bagaimana saya harus menangani ini?

Jawaban:


146

Fungsi NumPy np.stdmengambil parameter opsional ddof: "Delta Degrees of Freedom". Secara default, ini 0. Setel 1untuk mendapatkan hasil MATLAB:

>>> np.std([1,3,4,6], ddof=1)
2.0816659994661326

Untuk menambahkan lebih banyak konteks, dalam perhitungan varians (yang deviasinya standarnya adalah akar kuadrat) kita biasanya membagi dengan jumlah nilai yang kita miliki.

Tetapi jika kita memilih sampel acak dari Nelemen dari distribusi yang lebih besar dan menghitung varians, pembagian dengan Ndapat menyebabkan perkiraan varian yang sebenarnya terlalu rendah. Untuk mengatasinya, kita dapat menurunkan angka yang kita bagi ( derajat kebebasan ) ke angka yang kurang dari N(biasanya N-1). The ddofParameter memungkinkan kita mengubah pembagi dengan jumlah yang kita tentukan.

Kecuali diberitahu sebaliknya, NumPy akan menghitung penduga bias untuk varians ( ddof=0, dibagi dengan N). Inilah yang Anda inginkan jika Anda bekerja dengan seluruh distribusi (dan bukan subset nilai yang telah diambil secara acak dari distribusi yang lebih besar). Jika ddofparameter diberikan, NumPy akan membagi dengan N - ddof.

Perilaku default MATLAB stdadalah memperbaiki bias untuk varians sampel dengan membaginya dengan N-1. Ini menghilangkan beberapa (tapi mungkin tidak semua) bias dalam standar deviasi. Ini mungkin yang Anda inginkan jika Anda menggunakan fungsi tersebut pada sampel acak dari distribusi yang lebih besar.

Jawaban bagus dari @hbaderts memberikan detail matematis lebih lanjut.


4
Saya akan menambahkannya di Matlab, std([1 3 4 6],1)setara dengan default NumPy np.std([1,3,4,6]). Semua ini cukup jelas dijelaskan dalam dokumentasi untuk Matlab dan NumPy, jadi saya sangat menyarankan OP untuk membaca itu di masa mendatang.
horchler

Pada titik tertentu standar ini telah berubah: np.std () = np.std (ddof = 1), meskipun dokumentasi mengatakan bahwa np.std () harus default ke ddof = 0 ...
ColinMac

61

Simpangan baku adalah akar kuadrat dari varians. Varians variabel acak Xdidefinisikan sebagai

definisi varians

Oleh karena itu, penduga untuk varians adalah

penaksir bias

dimana sampel berartimenunjukkan mean sampel. Untuk dipilih secara acak xi, dapat ditunjukkan bahwa penduga ini tidak konvergen ke varian sebenarnya, tetapi ke

penduga yang tidak bias

Jika Anda memilih sampel secara acak dan memperkirakan mean dan varians sampel, Anda harus menggunakan estimator yang dikoreksi (tidak bias)

penduga yang tidak bias

yang akan menyatu sigma kuadrat. Istilah koreksi n-1juga disebut koreksi Bessel.

Sekarang secara default, MATLABs stdmenghitung berisi estimator dengan istilah koreksi n-1. Namun NumPy (seperti yang dijelaskan @ajcr) menghitung penaksir bias tanpa istilah koreksi secara default. Parameter ddofmemungkinkan untuk mengatur istilah koreksi apa pun n-ddof. Dengan mengaturnya ke 1 Anda mendapatkan hasil yang sama seperti di MATLAB.

Demikian pula, MATLAB memungkinkan untuk menambahkan parameter kedua w, yang menentukan "skema penimbangan". Default ,, w=0menghasilkan istilah koreksi n-1(penduga tidak bias), sedangkan untuk w=1, hanya n yang digunakan sebagai istilah koreksi (penduga bias).


2
Dalam rumus penduga terkoreksi, faktor n (dalam jumlah) tidak boleh ada.
Frunobulax

3
Intuisi di balik suku n-1 dalam varians: Anda sudah menggunakan sampel Anda untuk memperkirakan mean yang akan Anda gunakan untuk mendekati varians. Ini memperkenalkan korelasi dan dengan demikian ddof harus 1.
Matthias

@Frunobulax Saya telah memperbaiki kesalahan ketik untuk anak cucu. Apa yang terjadi dalam persamaan asli adalah batas atas jumlah tersebut tidak diberikan dengan benar. Alih-alih nberada di atas notasi penjumlahan, ia masuk ke dalam penjumlahan.
rayryeng

5

Untuk orang yang tidak ahli dalam statistik, panduan sederhana adalah:

  • Sertakan ddof=1jika Anda menghitung np.std()sampel yang diambil dari kumpulan data lengkap Anda.

  • Pastikan ddof=0jika Anda menghitung np.std()populasi penuh

DDOF disertakan untuk sampel untuk mengimbangi bias yang dapat terjadi pada angka.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.