Quantile-Quantile Plot โดยใช้ SciPy


87

คุณจะสร้าง qq-plot โดยใช้ Python ได้อย่างไร

สมมติว่าคุณมีชุดการวัดจำนวนมากและกำลังใช้ฟังก์ชันการลงจุดที่รับค่า XY เป็นอินพุต ฟังก์ชันควรลงจุดควอนไทล์ของการวัดเทียบกับควอนไทล์ที่สอดคล้องกันของการแจกแจงบางส่วน (ปกติสม่ำเสมอ ... )

พล็อตผลลัพธ์ช่วยให้เราสามารถประเมินในการวัดของเราเป็นไปตามการแจกแจงที่สันนิษฐานหรือไม่

http://en.wikipedia.org/wiki/Quantile-quantile_plot

ทั้ง R และ Matlab มีฟังก์ชันสำเร็จรูปสำหรับสิ่งนี้ แต่ฉันสงสัยว่าวิธีการที่สะอาดที่สุดสำหรับการนำไปใช้ใน Python คืออะไร


2
คุณได้ดูprobplot? docs.scipy.org/doc/scipy/reference/generated/…
Geoff

1
qqplot และ Probplots พร้อมตัวเลือกมากมาย: statsmodels.sourceforge.net/devel/…
Josef

คำตอบ:


105

ฉันคิดว่าscipy.stats.probplotจะทำในสิ่งที่คุณต้องการ ดูเอกสารสำหรับรายละเอียดเพิ่มเติม

import numpy as np 
import pylab 
import scipy.stats as stats

measurements = np.random.normal(loc = 20, scale = 5, size=100)   
stats.probplot(measurements, dist="norm", plot=pylab)
pylab.show()

ผลลัพธ์

ใส่คำอธิบายภาพที่นี่


บางครั้งฉันเคยเห็นเส้นประความเชื่อมั่นที่แคบลงตรงกลางและเป็นเหมือนทรัมเป็ตในตอนท้าย คุณสามารถเพิ่ม "เส้นแนะนำ" เหล่านี้ลงในโครงเรื่องได้หรือไม่
Norfeldt

21
ตกลง แต่นี่คือพล็อตความน่าจะเป็น (ตัวอย่างเทียบกับการแจกแจงเชิงทฤษฎี) พล็อต qq เปรียบเทียบสองตัวอย่าง itl.nist.gov/div898/handbook/eda/section3/qqplot.htm itl.nist.gov/div898/handbook/eda/section3/probplot.htm
Ricky Robinson

7
@RickyRobinson ดูเหมือนว่าแหล่งข้อมูลหลายแห่ง (รวมถึงวิกิพีเดีย) จะขัดแย้งกับหนังสือคู่มือ NIST แหล่งข้อมูลอื่น ๆ ค่อนข้างมากระบุว่าพล็อต QQ มีปริมาณเชิงทฤษฎีบนแกนนอนและปริมาณข้อมูลในแนวตั้ง ไม่ว่าในกรณีใดความแตกต่างนั้นเป็นเชิงวิชาการ: การวางแผนตัวอย่างเป็นหลักเหมือนกับการใช้ฟังก์ชันการแจกแจงเชิงประจักษ์ ไม่ว่าจะด้วยวิธีใดคุณกำลังวางแผนปริมาณของ dsitribution หนึ่งเทียบกับอีกทางหนึ่ง
Peter

1
ฉันเห็นด้วยกับ @RickyRobinson นี่ไม่ใช่คำตอบที่ถูกต้องสำหรับคำถามนี้ พล็อต QQ และพร็อพพร็อพแตกต่างกันแม้ว่าทั้งคู่จะมีการแจกแจงแบบใดแบบหนึ่งเทียบกับอีกแบบหนึ่ง
Florent

49

การใช้qqplotของstatsmodels.apiเป็นตัวเลือกอื่น:

ตัวอย่างพื้นฐานมาก:

import numpy as np
import statsmodels.api as sm
import pylab

test = np.random.normal(0,1, 1000)

sm.qqplot(test, line='45')
pylab.show()

ผลลัพธ์:

ใส่คำอธิบายภาพที่นี่

เอกสารและตัวอย่างอื่น ๆ อยู่ที่นี่


1
@ tommy.carstensen จงใจแยกจากscipyถึงstatsmodels
SARose

5
เพียงแค่ทราบ ตัวอย่างของคุณขีดเส้นสำหรับการแจกแจงปกติมาตรฐาน เพื่อให้ได้เส้นมาตรฐาน (ปรับขนาดโดยค่าเบี่ยงเบนมาตรฐานของตัวอย่างที่กำหนดและเพิ่มค่าเฉลี่ย) เช่นในตัวอย่าง @Geoff คุณต้องตั้งค่า line = 's' แทน line = '45 '
Mike

+1 สำหรับคำตอบนี้ ฉันคิดว่าการมุ่งเน้นทรัพยากรให้มากขึ้นในแพ็กเกจเดียวสำหรับสถิติเป็นสิ่งสำคัญ statsmodelsจะเป็นทางเลือกที่ดี
Ken T

20

หากคุณต้องการทำพล็อต QQ ของตัวอย่างหนึ่งกับอีกตัวอย่างหนึ่ง statsmodels จะรวม qqplot_2samples () เช่นเดียวกับ Ricky Robinson ในความคิดเห็นด้านบนนี่คือสิ่งที่ฉันคิดว่าเป็นพล็อต QQ เทียบกับพล็อตความน่าจะเป็นซึ่งเป็นตัวอย่างเทียบกับการแจกแจงเชิงทฤษฎี

http://statsmodels.sourceforge.net/devel/generated/statsmodels.graphics.gofplots.qqplot_2samples.html


11
การใช้งาน qqplot นี้ดูเหมือนจะไม่สามารถจัดการกับตัวอย่างที่มีขนาดต่างกันได้ซึ่งเป็นเรื่องตลกเพราะข้อดีอย่างหนึ่งของพล็อต QQ คือสามารถเปรียบเทียบตัวอย่างที่มีขนาดต่างกันได้ ...
Robert Muil

5

ฉันคิดสิ่งนี้ขึ้นมา บางทีคุณอาจปรับปรุงได้ โดยเฉพาะอย่างยิ่งวิธีการสร้างควอนไทล์ของการกระจายดูเหมือนจะยุ่งยากสำหรับฉัน

คุณสามารถแทนที่np.random.normalด้วยการแจกแจงอื่น ๆnp.randomเพื่อเปรียบเทียบข้อมูลกับการแจกแจงอื่น ๆ

#!/bin/python

import numpy as np

measurements = np.random.normal(loc = 20, scale = 5, size=100000)

def qq_plot(data, sample_size):
    qq = np.ones([sample_size, 2])
    np.random.shuffle(data)
    qq[:, 0] = np.sort(data[0:sample_size])
    qq[:, 1] = np.sort(np.random.normal(size = sample_size))
    return qq

print qq_plot(measurements, 1000)


2

เพื่อเพิ่มความสับสนเกี่ยวกับแผน QQ และแผนความน่าจะเป็นในโลก Python และ R นี่คือสิ่งที่คู่มือ SciPyกล่าวว่า:

" probplotสร้างพล็อตความน่าจะเป็นซึ่งไม่ควรสับสนกับ QQ หรือพล็อต PP Statsmodels มีฟังก์ชันประเภทนี้ที่ครอบคลุมมากขึ้นโปรดดู statsmodels.api.ProbPlot"

หากคุณลองscipy.stats.probplotคุณจะเห็นว่ามันเปรียบเทียบชุดข้อมูลกับการแจกแจงเชิงทฤษฎี แปลง QQ, OTOH เปรียบเทียบชุดข้อมูลสองชุด (ตัวอย่าง)

R มีฟังก์ชั่นqqnorm, และqqplot qqlineจากวิธีใช้ R (เวอร์ชัน 3.6.3):

qqnormเป็นฟังก์ชันทั่วไปซึ่งเป็นวิธีการเริ่มต้นที่สร้างพล็อต QQ ปกติของค่าใน y qqlineเพิ่มบรรทัดให้กับ "เชิงทฤษฎี" โดยค่าเริ่มต้นพล็อตควอนไทล์ - ควอนไทล์ปกติซึ่งผ่านควอนไทล์โพรบโดยค่าเริ่มต้นควอร์ไทล์ที่หนึ่งและสาม

qqplot สร้างพล็อต QQ ของชุดข้อมูลสองชุด

ในระยะสั้นของ R qqnormมีฟังก์ชันการทำงานเดียวกันกับที่ให้บริการด้วยการตั้งค่าเริ่มต้นscipy.stats.probplot dist=normแต่ความจริงที่ว่าพวกเขาเรียกมันqqnormและควรจะ "สร้างพล็อต QQ ธรรมดา" อาจทำให้ผู้ใช้สับสนได้ง่าย

ในที่สุดคำเตือน แผนการเหล่านี้ไม่ได้แทนที่การทดสอบทางสถิติที่เหมาะสมและควรใช้เพื่อวัตถุประสงค์ในการอธิบายเท่านั้น


1

คุณสามารถใช้โบเก้

from bokeh.plotting import figure, show
from scipy.stats import probplot
# pd_series is the series you want to plot
series1 = probplot(pd_series, dist="norm")
p1 = figure(title="Normal QQ-Plot", background_fill_color="#E8DDCB")
p1.scatter(series1[0][0],series1[0][1], fill_color="red")
show(p1)

1
import numpy as np 
import pylab 
import scipy.stats as stats
measurements = np.random.normal(loc = 20, scale = 5, size=100)   
stats.probplot(measurements, dist="norm", plot=pylab)
pylab.show()

ต่อไปนี้พล็อตจะวาดการวัดกราฟเทียบกับการแจกแจงปกติซึ่งแสดงใน dist = "norm"


0

ตัวอย่างของคุณใหญ่แค่ไหน? นี่คืออีกทางเลือกหนึ่งในการทดสอบข้อมูลของคุณจากการจัดจำหน่ายใด ๆ โดยใช้ห้องสมุด OpenTURNS ในตัวอย่างด้านล่างฉันสร้างตัวอย่าง x จำนวน 1.000.000 จากการแจกแจงแบบสม่ำเสมอและทดสอบเทียบกับการแจกแจงปกติ คุณสามารถแทนที่ x ด้วยข้อมูลของคุณได้หากคุณจัดรูปแบบใหม่เป็นx= [[x1], [x2], .., [xn]]

import openturns as ot

x = ot.Uniform().getSample(1000000)
g = ot.VisualTest.DrawQQplot(x, ot.Normal())
g

ในสมุดบันทึก Jupyter ของฉันฉันเห็น: ใส่คำอธิบายภาพที่นี่

หากคุณกำลังเขียนสคริปต์คุณสามารถทำได้อย่างถูกต้องมากขึ้น

from openturns.viewer import View`
import matplotlib.pyplot as plt
View(g)
plt.show()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.