เหตุใด numpy std () จึงให้ผลลัพธ์ที่แตกต่างกับ matlab std ()


88

ฉันพยายามแปลงรหัส matlab เป็น numpy และพบว่า numpy มีผลลัพธ์ที่แตกต่างกับฟังก์ชัน std

ใน matlab

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

เป็นตัวเลข

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

เป็นเรื่องปกติหรือไม่? และควรจัดการกับเรื่องนี้อย่างไร?

คำตอบ:


146

ฟังก์ชัน NumPy np.stdรับพารามิเตอร์ที่เป็นทางเลือกddof: "Delta Degrees of Freedom" 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เรียกอีกอย่างว่าการแก้ไขของ Bessel

ในขณะนี้โดยค่าเริ่มต้น MATLABs stdคำนวณเป็นกลางn-1ประมาณการที่มีระยะเวลาการแก้ไข อย่างไรก็ตาม NumPy (ตามที่ @ajcr อธิบาย) จะคำนวณตัวประมาณค่าแบบเอนเอียงโดยไม่มีเงื่อนไขการแก้ไขตามค่าเริ่มต้น พารามิเตอร์ที่จะช่วยให้การตั้งระยะการแก้ไขใดddofn-ddofเมื่อตั้งค่าเป็น 1 คุณจะได้ผลลัพธ์เช่นเดียวกับใน MATLAB

ในทำนองเดียวกัน MATLAB อนุญาตให้เพิ่มพารามิเตอร์ที่สองwซึ่งระบุ "รูปแบบการชั่งน้ำหนัก" ค่าดีฟอลต์w=0ผลลัพธ์เป็นเงื่อนไขการแก้ไขn-1(ตัวประมาณที่เป็นกลาง) ในขณะที่สำหรับw=1n เท่านั้นที่ใช้เป็นเงื่อนไขการแก้ไข (ตัวประมาณค่าเอนเอียง)


2
ในสูตรสำหรับตัวประมาณค่าที่ถูกต้องไม่ควรมีตัวประกอบn (ภายในผลรวม)
Frunobulax

3
สัญชาตญาณที่อยู่เบื้องหลังพจน์ n-1 ในความแปรปรวน: คุณได้ใช้ตัวอย่างของคุณในการประมาณค่าเฉลี่ยที่คุณจะใช้ในการประมาณค่าความแปรปรวนแล้ว สิ่งนี้แนะนำความสัมพันธ์ดังนั้น ddof จะต้องเป็น 1
Matthias

@Frunobulax ฉันได้แก้ไขการพิมพ์ผิดสำหรับลูกหลาน สิ่งที่เกิดขึ้นในสมการเดิมคือขีด จำกัด บนของผลรวมไม่ได้รับการแสดงผลอย่างถูกต้อง แทนที่จะnไปที่ด้านบนสุดของสัญกรณ์ผลรวมมันกลับเข้าไปในผลรวม
rayryeng

5

สำหรับคนที่ไม่ค่อยเก่งเรื่องสถิติคำแนะนำง่ายๆคือ:

  • รวมddof=1ถ้าคุณกำลังคำนวณnp.std()สำหรับตัวอย่างที่นำมาจากชุดข้อมูลทั้งหมดของคุณ

  • ตรวจสอบddof=0ว่าคุณกำลังคำนวณnp.std()สำหรับประชากรทั้งหมดหรือไม่

DDOF รวมอยู่ในตัวอย่างเพื่อถ่วงดุลอคติที่อาจเกิดขึ้นในตัวเลข

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.