Quantil-Quantil-Plot mit SciPy

84

Wie würden Sie mit Python ein QQ-Diagramm erstellen?

Angenommen, Sie haben eine große Anzahl von Messungen und verwenden eine Plotfunktion, die XY-Werte als Eingabe verwendet. Die Funktion sollte die Quantile der Messungen gegen die entsprechenden Quantile einer bestimmten Verteilung (normal, einheitlich ...) auftragen.

Das resultierende Diagramm lässt uns dann bewerten, ob unsere Messung der angenommenen Verteilung folgt oder nicht.

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

Sowohl R als auch Matlab bieten hierfür vorgefertigte Funktionen, aber ich frage mich, welche Methode für die Implementierung in Python am saubersten wäre.

John
quelle
2
Hast du angeschaut probplot? docs.scipy.org/doc/scipy/reference/generated/…
Geoff
1
qqplot und probplots mit vielen Optionen: statsmodels.sourceforge.net/devel/…
Josef

Antworten:

105

Ich denke, das scipy.stats.probplotwird tun, was Sie wollen. Weitere Informationen finden Sie in der Dokumentation .

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

Ergebnis

Geben Sie hier die Bildbeschreibung ein

Geoff
quelle
Manchmal habe ich einige gepunktete Vertrauenslinien gesehen, die sich in der Mitte verengen und an den Enden wie eine Trompete wirken. Können Sie diese "Richtlinien" zum Plot hinzufügen?
Norfeldt
21
Ok, aber dies ist ein Wahrscheinlichkeitsdiagramm (eine Stichprobe gegen eine theoretische Verteilung). Ein qq-Diagramm vergleicht zwei Proben. itl.nist.gov/div898/handbook/eda/section3/qqplot.htm itl.nist.gov/div898/handbook/eda/section3/probplot.htm
Ricky Robinson
7
@ RickyRobinson Es scheint, dass viele Quellen (einschließlich Wikipedia) dem NIST-Handbuch widersprechen. So gut wie jede andere Quelle gibt an, dass ein QQ-Diagramm theoretische Quantile auf der horizontalen Achse und Datenquantile vertikal enthält. In jedem Fall ist die Unterscheidung akademisch: Das Zeichnen einer Stichprobe entspricht im Wesentlichen der Verwendung der empirischen Verteilungsfunktion. In beiden Fällen zeichnen Sie die Quantile einer Verteilung gegen eine andere.
Peter
1
Ich stimme @RickyRobinson zu, dies ist nicht die richtige Antwort auf diese Frage. QQ-Diagramme und Prob-Diagramme unterscheiden sich, obwohl beide Quantile einer Verteilung gegen eine andere verteilt sind.
Florent
48

Die Verwendung qqplotvon statsmodels.apiist eine weitere Option:

Sehr einfaches Beispiel:

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

Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Dokumentation und weitere Beispiele finden Sie hier

Akavall
quelle
1
@ Tommy.carstensen es wurde absichtlich von scipyzustatsmodels
SARose
3
Nur eine Notiz. Ihr Beispiel zeichnet die Linie für die Standardnormalverteilung. Um eine standardisierte Linie (skaliert mit der Standardabweichung der angegebenen Stichprobe und Addition des Mittelwerts) wie im @ Geoff-Beispiel zu erhalten, müssen Sie line = 's' anstelle von line = '45 'setzen
Mike
+1 für diese Antwort. Ich denke, es ist wichtig, mehr Ressourcen auf ein einziges Statistikpaket zu konzentrieren. statsmodelswäre eine gute Wahl.
Ken T
20

Wenn Sie ein QQ-Diagramm eines Samples gegen ein anderes erstellen müssen, enthält statsmodels qqplot_2samples (). Wie Ricky Robinson in einem Kommentar oben ist dies das, was ich als QQ-Diagramm gegen ein Wahrscheinlichkeitsdiagramm betrachte, das eine Stichprobe gegen eine theoretische Verteilung ist.

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

ccap
quelle
11
Diese qqplot-Implementierung scheint keine Samples mit unterschiedlichen Größen zu verarbeiten, was lustig ist, da einer der großen Vorteile eines QQ-Plots darin besteht, dass man Samples mit unterschiedlichen Größen vergleichen kann ...
Robert Muil
5

Ich habe mir das ausgedacht. Vielleicht kannst du es verbessern. Insbesondere die Methode zur Erzeugung der Quantile der Verteilung erscheint mir umständlich.

Sie können durch np.random.normaljede andere Distribution von ersetzen np.random, um Daten mit anderen Distributionen zu vergleichen.

#!/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)
John
quelle
2
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()

Hier zeichnen Probplot die Graphenmessungen gegen die Normalverteilung, die in dist = "norm" speofied sind.

Ravi G.
quelle
2

Um die Verwirrung um QQ-Diagramme und Wahrscheinlichkeitsdiagramme in der Python- und R-Welt zu vergrößern, heißt es im SciPy-Handbuch :

" probplotErzeugt ein Wahrscheinlichkeitsdiagramm, das nicht mit einem QQ- oder PP-Diagramm verwechselt werden sollte. Statsmodels verfügt über eine umfangreichere Funktionalität dieses Typs, siehe statsmodels.api.ProbPlot."

Wenn Sie es ausprobieren scipy.stats.probplot, werden Sie feststellen, dass tatsächlich ein Datensatz mit einer theoretischen Verteilung verglichen wird. QQ-Diagramme, OTOH, vergleichen zwei Datensätze (Proben).

R hat Funktionen qqnorm, qqplotund qqline. Aus der R-Hilfe (Version 3.6.3):

qqnormist eine generische Funktion, deren Standardmethode ein normales QQ-Diagramm der Werte in y erzeugt. qqlineFügt eine Linie zu einem „theoretischen“, standardmäßig normalen Quantil-Quantil-Diagramm hinzu, das durch die Probs-Quantile verläuft, standardmäßig das erste und dritte Quartil.

qqplot Erzeugt ein QQ-Diagramm mit zwei Datensätzen.

Kurz gesagt, Rs qqnormbieten die gleiche Funktionalität wie scipy.stats.probplotdie Standardeinstellung dist=norm. Aber die Tatsache, dass sie es genannt haben qqnormund dass es "ein normales QQ-Diagramm erzeugen" soll, kann Benutzer leicht verwirren.

Zum Schluss noch ein warnendes Wort. Diese Diagramme ersetzen keine ordnungsgemäßen statistischen Tests und sollten nur zur Veranschaulichung verwendet werden.

Kehlkopf Decidua
quelle
1

Sie können Bokeh verwenden

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)
Sushmit
quelle