Lô đất định lượng-lượng tử sử dụng SciPy


85

Bạn sẽ tạo một qq-plot bằng Python như thế nào?

Giả sử rằng bạn có một tập hợp lớn các phép đo và đang sử dụng một số hàm vẽ đồ thị lấy giá trị XY làm đầu vào. Hàm phải vẽ biểu đồ lượng tử của các phép đo so với các lượng tử tương ứng của một số phân bố (chuẩn, đồng nhất ...).

Biểu đồ kết quả sau đó cho phép chúng tôi đánh giá trong phép đo của chúng tôi có tuân theo phân phối giả định hay không.

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

Cả R và Matlab đều cung cấp các hàm được tạo sẵn cho việc này, nhưng tôi đang tự hỏi phương pháp sạch nhất để triển khai bằng Python sẽ là gì.


2
Bạn đã xem probplotchưa? docs.scipy.org/doc/scipy/reference/generated/…
Geoff

1
qqplot và các lô thăm dò với nhiều lựa chọn: statsmodels.sourceforge.net/devel/…
Josef

Câu trả lời:


105

Tôi nghĩ rằng điều đó scipy.stats.probplotsẽ làm những gì bạn muốn. Xem tài liệu để biết thêm chi tiết.

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()

Kết quả

nhập mô tả hình ảnh ở đây


Đôi khi tôi đã thấy một số đường tự tin có dấu chấm nhỏ hẹp ở giữa và giống như một chiếc kèn ở cuối. Bạn có thể thêm những "dòng hướng dẫn" này vào cốt truyện không?
Norfeldt

21
Ok, nhưng đây là biểu đồ xác suất (mẫu so với phân phối lý thuyết). Một biểu đồ qq so sánh hai mẫu. itl.nist.gov/div898/handbook/eda/section3/qqplot.htm itl.nist.gov/div898/handbook/eda/section3/probplot.htm
Ricky Robinson

7
@RickyRobinson Có vẻ như nhiều nguồn (bao gồm cả wikipedia) mâu thuẫn với sổ tay NIST. Khá nhiều nguồn khác nói rằng một biểu đồ QQ có các lượng tử lý thuyết trên trục hoành và các lượng tử dữ liệu theo chiều dọc. Trong mọi trường hợp, sự khác biệt là mang tính học thuật: vẽ mẫu về cơ bản giống như sử dụng hàm phân phối thực nghiệm. Dù bằng cách nào, bạn cũng đang lập mưu đồ của một lượng tử phân phối này chống lại một lượng tử khác.
Peter

1
Tôi đồng ý với @RickyRobinson, đây không phải là câu trả lời chính xác cho câu hỏi này. Các âm mưu QQ và âm mưu xác suất là khác nhau mặc dù chúng đều là lượng tử của một phân phối so với một phân phối khác.
Florent

48

Sử dụng qqplotof statsmodels.apilà một tùy chọn khác:

Ví dụ rất cơ bản:

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()

Kết quả:

nhập mô tả hình ảnh ở đây

Tài liệu và nhiều ví dụ khác ở đây


1
@ tommy.carstensen nó đã được cố tình tách khỏi scipythànhstatsmodels
SARose

3
Chỉ là một ghi chú. Ví dụ của bạn vẽ đường cho phân phối chuẩn chuẩn. Để có được một đường chuẩn hóa (được chia tỷ lệ theo độ lệch chuẩn của mẫu đã cho và có thêm giá trị trung bình) như trong ví dụ @Geoff, bạn cần đặt line = 's' thay vì line = '45 '
Mike

+1 cho câu trả lời này. Tôi nghĩ điều quan trọng là phải tập trung nhiều nguồn lực hơn vào một gói duy nhất để thống kê. statsmodelssẽ là một lựa chọn tốt.
Ken T

20

Nếu bạn cần thực hiện một biểu đồ QQ của mẫu này so với mẫu khác, thì các mô hình thống kê bao gồm qqplot_2samples (). Giống như Ricky Robinson trong một bình luận ở trên, đây là những gì tôi nghĩ về một âm mưu QQ so với một âm mưu xác suất là một mẫu chống lại phân phối lý thuyết.

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


11
Thực hiện qqplot này dường như không để xử lý mẫu với kích cỡ khác nhau, đó là hài hước vì một trong những lợi thế lớn của một âm mưu QQ là người ta có thể so sánh mẫu với kích cỡ khác nhau ...
Robert Muil

5

Tôi đã nghĩ ra điều này. Có lẽ bạn có thể cải thiện nó. Đặc biệt là phương pháp tạo các lượng tử của phân phối có vẻ rườm rà đối với tôi.

Bạn có thể thay thế np.random.normalbằng bất kỳ bản phân phối nào khác np.randomđể so sánh dữ liệu với các bản phân phối khác.

#!/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

Để thêm vào sự nhầm lẫn xung quanh các âm mưu QQ và các lô xác suất trong thế giới Python và R, đây là những gì hướng dẫn SciPy nói:

" probplottạo ra một biểu đồ xác suất, không nên nhầm lẫn với một biểu đồ QQ hoặc một PP. Statsmodels có nhiều chức năng mở rộng hơn của loại này, xem statsmodels.api.ProbPlot."

Nếu bạn thử scipy.stats.probplot, bạn sẽ thấy rằng thực sự nó so sánh một tập dữ liệu với một phân phối lý thuyết. Lô QQ, OTOH, so sánh hai tập dữ liệu (mẫu).

R có các chức năng qqnorm, qqplotqqline. Từ trợ giúp R ​​(Phiên bản 3.6.3):

qqnormlà một hàm chung phương pháp mặc định tạo ra một đồ thị QQ bình thường của các giá trị trong y. qqlinethêm một dòng vào một đồ thị lượng tử-lượng tử bình thường, theo mặc định, thông thường, đi qua các lượng tử thăm dò, theo mặc định là phần tư thứ nhất và thứ ba.

qqplot tạo ra một âm mưu QQ gồm hai tập dữ liệu.

Tóm lại, R's qqnormcung cấp chức năng tương tự như scipy.stats.probplotcài đặt mặc định dist=norm. Nhưng việc họ gọi nó qqnormvà nó được cho là "sản xuất một âm mưu QQ bình thường" có thể dễ khiến người dùng nhầm lẫn.

Cuối cùng, một lời cảnh báo. Những biểu đồ này không thay thế việc kiểm tra thống kê thích hợp và chỉ nên được sử dụng cho mục đích minh họa.


2

Làm thế nào lớn là mẫu của bạn? Đây là một tùy chọn khác để kiểm tra dữ liệu của bạn so với bất kỳ phân phối nào bằng thư viện OpenTURNS . Trong ví dụ dưới đây, tôi tạo một mẫu x 1.000.000 số từ phân phối Đồng nhất và kiểm tra nó với phân phối Chuẩn. Bạn có thể thay thế x bằng dữ liệu của mình nếu bạn định hình lại nó thànhx= [[x1], [x2], .., [xn]]

import openturns as ot

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

Trong Sổ tay Jupyter của tôi, tôi thấy: nhập mô tả hình ảnh ở đây

Nếu bạn đang viết một kịch bản, bạn có thể làm đúng hơn

from openturns.viewer import View`
import matplotlib.pyplot as plt
View(g)
plt.show()

1

Bạn có thể sử dụng hiệu ứng bokeh

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()

Tại đây probplot vẽ các phép đo biểu đồ so với phân phối chuẩn được trình bày trong dist = "norm"

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.