Standardabweichung mit Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
acidk
User
Beiträge: 75
Registriert: Samstag 6. Januar 2007, 18:54
Wohnort: Braunschweig

Hallo Leute!
Ich möchte mit Python eine Standardabweichung berechnen - habe es bisher mit
numpy versucht, allerdings wird hier nicht mit n-1 normalisiert, sondern mit n!

Weiß von Euch jemand, wie ich die "richtige"(= std mit n-1) berechnen kann?

Code:

Code: Alles auswählen

from numpy import*
a = array([[1.5, 3.5, 0.5 ]])
print a.std()
liefert statt 1.527-->1.247

Besten Dank!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hmm, mit Zwölftklassmathematik sieht das so aus:

Code: Alles auswählen

>>> values = [1.5, 3.5, 0.5]
>>> erw = sum(values) / len(values)
>>> erw
1.8333333333333333
>>> erw2 = sum(item**2 for item in values) / len(values)
>>> erw2
4.916666666666667
>>> var = erw2 - erw**2
1.5555555555555562
>>> var**0.5
1.2472191289246475
(Verschiebungsregel, FYI)

Hilft dir das weiter?
Zuletzt geändert von Leonidas am Montag 21. April 2008, 12:57, insgesamt 1-mal geändert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

Code: Alles auswählen

In [1]: from scipy import *

In [2]: a = array([1.5, 3.5, 0.5 ])

In [3]: stats.std(a)
Out[3]: 1.52752523165

In [4]: stats.stderr(a)
Out[4]: 0.881917103688

In [5]: a.var()
Out[5]: 1.55555555556
Beachte, daß ich für das array eine Ebene Klammern weggelassen habe. Das Verhalten von numpy ist korrekt: numpy.std bezieht sich auf N und nicht N-1.

Gruß,
Christian

edit: Grammatik :oops:
acidk
User
Beiträge: 75
Registriert: Samstag 6. Januar 2007, 18:54
Wohnort: Braunschweig

@CM

Thats it! Vielen Dank!

merkwürdig finde ich, dass scipy scheinbar länger braucht als numpy...
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Das kann ich bei mir nicht nachvollziehen. Aber andererseits finde ich den Namespace nicht konsistent: Zwei verschiedene std()-Funktionen zu haben ist schlicht seltsam. Besser wäre vielleicht std() und stdn() oder die Möglichkeit std() mitteilen zu können, welches Verhalten man wünscht.

Wie seht ihr das? Ist das 'nen Featurerequest wert?

Christian
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

CM hat geschrieben:Das Verhalten von numpy ist korrekt: numpy.std bezieht sich auf N und nicht N-1.
Ist das irgendwo dokumentiert?
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Ja:
- in numpy hat (nahezu) jede Funktion einen Docstring.
- es gibt die API-Documentation (da steht es seltsamerweise nicht drin): http://scipy.org/doc/numpy_api_docs/num ... c.html#std
- vor allem aber gibt es eine Umfangreiche Sammlung von Beispielen, inkl. einer "Docstringwiederholung": http://www.scipy.org/Numpy_Example_List ... 620f804ac2

Vielleicht gibt es noch mehr Anlaufpunkte, aber die fallen mir gerade nicht ein - ist noch früh ... ;-)

Gruß,
Christian
acidk
User
Beiträge: 75
Registriert: Samstag 6. Januar 2007, 18:54
Wohnort: Braunschweig

Ich hatte die Info aus jener gelisteten Beispielliste!
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Und da steht:
The computed standard deviation is biased, i.e., the mean is computed
by dividing by the number of elements, N, rather than by N-1.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

CM hat geschrieben:Und da steht:
The computed standard deviation is biased, i.e., the mean is computed
by dividing by the number of elements, N, rather than by N-1.
Hmm, steht bei mir nicht im Docstring. Vielleicht liegts ja daran, dass ich nur Version 1.0.1 habe.
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Leonidas hat geschrieben:Hmm, mit Zwölftklassmathematik sieht das so aus:

Code: Alles auswählen

>>> values = [1.5, 3.5, 0.5]
>>> erw = sum(values) / len(values)
>>> erw
1.8333333333333333
>>> erw2 = sum(item**2 for item in values) / len(values)
>>> erw2
4.916666666666667
>>> var = erw2 - erw**2
1.5555555555555562
>>> var**0.5
1.2472191289246475
(Verscheibungsregel, FYI)

Hilft dir das weiter?
Wäre das aber nicht eher:

Code: Alles auswählen

erw2 = sum(((item-erw)**2 for item in values)/(len(values)-1)
logisch
User
Beiträge: 2
Registriert: Sonntag 18. April 2021, 00:15

Da die Frage mittlerweile (oder schon immer?) technisch gesehen eine noch bessere Antwort verdient hat, und weil sicher immer mal wieder jemand über Google hier landet, hiermit nun ein weiterer Beitrag:

Bei Standard-Abweichung und Varianz gibt es zwei relevante "Methodiken".
  • Die eine nimmt eine Stichprobe it der Anzahl n, wird auch die empirische Methode genannt, und benutzt einen Faktor von 1/(n-1). (Englisch: unbiased sample variance)
  • Die andere nimmt die (Grund-)Gesamtheit mit der Anzahl N und benutzt einen Faktor von 1/N. (Englisch: variance, population variance, evtl. auch "basic variance")
Für gängige Formelzeichen, Formeln und weitere Beispiele, siehe auch: https://www.scribbr.de/statistik/standardabweichung/

Code: Alles auswählen

import numpy as np
a = np.array([[1.5, 3.5, 0.5 ]])

print (np.average(a)) # 1.8333333333333333

# ddof int, optional
# Means Delta Degrees of Freedom.
# The divisor used in calculations is N - ddof,
# where N represents the number of elements.
# By default ddof is zero.
# source for this comment: https://numpy.org/doc/stable/reference/generated/numpy.std.html

print (a.std())       # 1.247219128924647
print (a.std(ddof=0)) # 1.247219128924647
print (a.std(ddof=1)) # 1.5275252316519468

print (a.var())       # 1.5555555555555556
print (a.var(ddof=0)) # 1.5555555555555556
print (a.var(ddof=1)) # 2.3333333333333335

print (a)             # [[1.5 3.5 0.5]]
logisch
User
Beiträge: 2
Registriert: Sonntag 18. April 2021, 00:15

PS: scipy ist dazu über gegangen die betreffenden Funktionen als "deprecated", also abgekündigt zu markieren. Sie verweisen darauf, dass man bitte auf numpy umsteigen soll. Damit bereinigt sich was und der Wartungsaufwand geht auch zurück.
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

Alternativ kann man auch die entsprechenden Funktion aus dem "statistics"-Modul aus der Standardbibliothek verwenden.
Antworten