คำนวณช่วงความเชื่อมั่นจากข้อมูลตัวอย่าง


112

ฉันมีข้อมูลตัวอย่างที่ฉันต้องการคำนวณช่วงความเชื่อมั่นโดยสมมติว่าเป็นการแจกแจงปกติ

ฉันพบและติดตั้งแพ็คเกจ numpy และ scipy แล้วและได้รับ numpy เพื่อส่งกลับค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐาน (numpy.mean (data) โดยมีข้อมูลเป็นรายการ) คำแนะนำใด ๆ ในการรับช่วงความมั่นใจตัวอย่างจะได้รับการชื่นชมมาก


1
ฉันคิดว่าคุณระบุแน่นอนว่าคุณต้องการคำนวณ CI สำหรับค่าเฉลี่ยตัวอย่างหรือค่าเฉลี่ยประชากร นั่นจะเป็นตัวกำหนดว่าคุณต้องการใช้การแจกแจงแบบปกติหรือ t เพื่อคำนวณ z-score และคำตอบด้านบนด้านล่างคือค่าเฉลี่ยตัวอย่างดังนั้นจึงใช้ที่การแจกแจง
Jake

คำตอบ:


166
import numpy as np
import scipy.stats


def mean_confidence_interval(data, confidence=0.95):
    a = 1.0 * np.array(data)
    n = len(a)
    m, se = np.mean(a), scipy.stats.sem(a)
    h = se * scipy.stats.t.ppf((1 + confidence) / 2., n-1)
    return m, m-h, m+h

คุณสามารถคำนวณแบบนี้ได้


1
sp.stats.stderr เลิกใช้แล้ว ฉันแทนที่ sp.stats.sem และมันก็ใช้งานได้ดี!
Bmayer0122

1
การนำเข้าscipyไม่จำเป็นต้องนำเข้าแพ็กเกจย่อยทั้งหมดโดยอัตโนมัติ ดีกว่าที่จะนำเข้าแพ็กเกจย่อยscipy.statsอย่างชัดเจน
Vikram

31
ระมัดระวังกับการใช้ "ส่วนตัว" sp.stats.t._ppfของ ฉันไม่สบายใจที่อยู่ในนั้นโดยไม่มีคำอธิบายเพิ่มเติม ใช้sp.stats.t.ppfโดยตรงดีกว่าเว้นแต่คุณจะแน่ใจว่าคุณรู้ว่ากำลังทำอะไรอยู่ ในการตรวจสอบอย่างรวดเร็วของแหล่งที่มา_ppfมีจำนวนเงินที่ยุติธรรมของรหัสข้ามกับ อาจไม่เป็นอันตราย แต่ก็อาจเป็นความพยายามเพิ่มประสิทธิภาพที่ไม่ปลอดภัยด้วย?
Russ

ฉันชอบมันเพราะคุณสามารถเพิ่มวิธี*ss.t._ppf((1+conf)/2.,n-1) ดาต้าเฟรมแพนด้าในตัวได้.semดังนั้นคุณไม่ต้องกังวลapply
ทีเอ็นที

1
เพียงต้องการชี้แจงการคำนวณนี้เป็นค่าเฉลี่ยตัวอย่างดังนั้นจึงใช้ที่การแจกแจง หากคำถามคือการคำนวณค่าเฉลี่ยประชากรควรใช้การแจกแจงแบบปกติและช่วงเวลาที่มั่นใจจะเล็กลงสำหรับระดับความเชื่อมั่นเดียวกัน
Jake

135

ต่อไปนี้เป็นโค้ดของ shasan แบบย่อโดยคำนวณช่วงความเชื่อมั่น 95% ของค่าเฉลี่ยอาร์เรย์a:

import numpy as np, scipy.stats as st

st.t.interval(0.95, len(a)-1, loc=np.mean(a), scale=st.sem(a))

แต่การใช้ StatsModels tconfint_meanเป็นเนื้อหาที่ดีกว่า:

import statsmodels.stats.api as sms

sms.DescrStatsW(a).tconfint_mean()

สมมติฐานพื้นฐานสำหรับทั้งสองคือตัวอย่าง (อาร์เรย์a) ถูกดึงออกมาโดยไม่ขึ้นกับการแจกแจงปกติโดยไม่ทราบค่าเบี่ยงเบนมาตรฐาน (ดูMathWorldหรือWikipedia )

สำหรับตัวอย่างขนาดใหญ่ n ค่าเฉลี่ยตัวอย่างจะกระจายตามปกติและสามารถคำนวณช่วงความเชื่อมั่นได้โดยใช้st.norm.interval()(ตามที่แนะนำในความคิดเห็นของ Jaime) แต่วิธีแก้ปัญหาข้างต้นก็ถูกต้องเช่นกันสำหรับ n ขนาดเล็กซึ่งst.norm.interval()ให้ช่วงความเชื่อมั่นที่แคบเกินไป (กล่าวคือ "ความมั่นใจปลอม") ดูคำตอบของฉันสำหรับคำถามที่คล้ายกันสำหรับรายละเอียดเพิ่มเติม (และหนึ่งในความคิดเห็นของ Russ ที่นี่)

ตัวอย่างที่ตัวเลือกที่ถูกต้องให้ (โดยพื้นฐาน) ช่วงความเชื่อมั่นที่เหมือนกัน:

In [9]: a = range(10,14)

In [10]: mean_confidence_interval(a)
Out[10]: (11.5, 9.4457397432391215, 13.554260256760879)

In [11]: st.t.interval(0.95, len(a)-1, loc=np.mean(a), scale=st.sem(a))
Out[11]: (9.4457397432391215, 13.554260256760879)

In [12]: sms.DescrStatsW(a).tconfint_mean()
Out[12]: (9.4457397432391197, 13.55426025676088)

และสุดท้ายผลลัพธ์ที่ไม่ถูกต้องโดยใช้st.norm.interval():

In [13]: st.norm.interval(0.95, loc=np.mean(a), scale=st.sem(a))
Out[13]: (10.23484868811834, 12.76515131188166)

1
ฉันเชื่อว่าคุณควรโทรst.t.interval(0.05)เพื่อรับช่วงความมั่นใจ 95%
Scimonster

5
ไม่st.t.interval(0.95)เป็นที่ถูกต้องสำหรับช่วงความเชื่อมั่น 95% ดูเอกสารscipy.stats.tสำหรับ การตั้งชื่อข้อโต้แย้งของ SciPy alphaดูเหมือนจะน้อยกว่าอุดมคติ
Ulrich Stern

ถ้าฉันมีข้อมูลสองอาร์เรย์แล้วคำนวณความแตกต่างของค่าเฉลี่ย มีวิธีใดบ้างที่จะได้ CI 95% สำหรับความแตกต่างค่าเฉลี่ยนี้? คุณนึกถึงวิธีง่ายๆในการทำเช่นเดียวกับที่คุณให้ไว้ที่นี่โดยใช้ StatsModelsl ได้ไหม
สตี

@steven ปรากฎว่าฉันตอบคำถามเกี่ยวกับเรื่องนี้ :)
Ulrich Stern

17

เริ่มต้นPython 3.8ไลบรารีมาตรฐานจัดเตรียมNormalDistวัตถุเป็นส่วนหนึ่งของstatisticsโมดูล:

from statistics import NormalDist

def confidence_interval(data, confidence=0.95):
  dist = NormalDist.from_samples(data)
  z = NormalDist().inv_cdf((1 + confidence) / 2.)
  h = dist.stdev * z / ((len(data) - 1) ** .5)
  return dist.mean - h, dist.mean + h

นี้:

  • สร้างNormalDistวัตถุจากตัวอย่างข้อมูล ( NormalDist.from_samples(data)ซึ่งจะช่วยให้เราสามารถเข้าถึงตัวอย่างของส่วนเบี่ยงเบนมาตรฐานค่าเฉลี่ยและผ่านและNormalDist.meanNormalDist.stdev

  • คำนวณZ-scoreตามการแจกแจงปกติมาตรฐาน (แสดงโดยNormalDist()) สำหรับความเชื่อมั่นที่กำหนดโดยใช้ค่าผกผันของฟังก์ชันการแจกแจงสะสม ( inv_cdf)

  • สร้างช่วงความเชื่อมั่นตามค่าเบี่ยงเบนมาตรฐานและค่าเฉลี่ยของกลุ่มตัวอย่าง


สิ่งนี้ถือว่าขนาดของกลุ่มตัวอย่างใหญ่พอ (สมมติว่ามากกว่า ~ 100 คะแนน) เพื่อที่จะใช้การแจกแจงปกติมาตรฐานแทนการแจกแจง t ของนักเรียนในการคำนวณzค่า


16

เริ่มต้นด้วยการค้นหาค่าzสำหรับช่วงความเชื่อมั่นที่คุณต้องการจากตารางค้นหา ช่วงความเชื่อมั่นแล้วmean +/- z*sigmaที่sigmaมีการประมาณค่าเบี่ยงเบนมาตรฐานของค่าเฉลี่ยตัวอย่างของคุณได้รับจากsigma = s / sqrt(n)ที่sเป็นส่วนเบี่ยงเบนมาตรฐานคำนวณจากข้อมูลตัวอย่างของคุณและnมีขนาดตัวอย่างของคุณ


29
scipy.stats.norm.interval(confidence, loc=mean, scale=sigma)
Jaime

5
ผู้ถามเดิมระบุว่าต้องถือว่าการแจกแจงแบบปกติ แต่ควรชี้ให้เห็นว่าสำหรับกลุ่มตัวอย่างขนาดเล็ก (N <100 หรือมากกว่านั้น) ควรค้นหา z ในการแจกแจงของ Student tแทนการแจกแจงปกติ . คำตอบของ shasan ทำสิ่งนี้อยู่แล้ว
รัส

3
@bogatron เกี่ยวกับแคลคูลัสที่แนะนำสำหรับช่วงความเชื่อมั่นจะไม่เป็นค่าเฉลี่ย +/- z * sigma / sqrt (n)โดยที่ n คือขนาดตัวอย่าง?
David

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