14.2    Lageparameter

Lageparameter sind die statistischen Kennzahlen einer Stichprobe, die das Zentrum der Daten beschreiben. Typische Lageparameter sind der Modus, der Median, der arithmetische Mittelwert, der harmonische Mittelwert und der geometrische Mittelwert. Die Verpackungsanlage müsste möglichst genau auf Mittelwerte von 50 g justiert werden.

14.2.1    Modus

Der Modus ist eine statistische Kennzahl, die angibt, welcher Messwert aus einer Messreihe am häufigsten vorkommt. Bezogen auf unser Beispiel bedeutet das: Welche Masse kommt am häufigsten in der Messreihe der eintausend Messwerte vor? Der folgende Konsolendialog zeigt, wie der Modus m aus der Stichprobe der tausend Einzelmassen mit der SciPy- Funktion mode(a) ermittelt wird:

>>> import numpy as np
>>> from scipy.stats import mode
>>> a=np.loadtxt('../daten.txt')
>>> m=mode(a)
>>> m
ModeResult(mode=array([49.9]), count=array([54]))
>>> m[0]
array([49.9])
>>> print(m[0])
[49.9]

Die Masse von 49,9 g kommt also insgesamt 54-mal vor.

Modus

Der Modus ist der Messwert einer Häufigkeitsverteilung, der am häufigsten vorkommt.

14.2.2    Median

Der Median, auch Zentralwert genannt, gibt den mittleren Wert einer sortierten Messreihe an, wenn die Anzahl der Messwerte ungerade ist. Falls die Anzahl gerade ist, wird der Mittelwert aus den beiden mittleren Messwerten berechnet.

formula

Der Median teilt die Messwerte in zwei Hälften. Die untere Hälfte ist kleiner als der Median, die obere Hälfte ist größer. Der Median ist robust gegen Ausreißer.

Median

Der Median teilt die sortierten Messwerte in zwei gleich große Hälften.

In der Regel liegen die Messwerte nicht sortiert vor. Wenn der Median berechnet werden soll, müssen die Messwerte also mit einem Sortieralgorithmus noch sortiert werden. Den folgenden Abschnitt brauchen Sie nicht zu lesen, wenn Sie bereits mit Sortieralgorithmen vertraut sind.

Exkurs: Sortieralgorithmen

Aus der Vielzahl der bekannten Sortieralgorithmen habe ich hier nur den Bubble Sort (Sortieren durch paarweises Vertauschen) und den Selection Sort (Sortieren durch Auswählen) ausgewählt. Mein Auswahlkriterium war nicht die Effektivität, sondern der einfache strukturelle Aufbau der beiden Algorithmen.

In jedem Sortieralgorithmus kommen zwei elementare Operationen vor: Vergleich und Tausch von Listenelementen. Jeder elementare Sortieralgorithmus besteht aus zwei ineinander verschachtelten Schleifen. In der äußeren Schleife erfasst eine Laufvariable i jede einzelne Position eines Listenelements. In der inneren Schleife erfasst eine Laufvariable j die nächste oder eine andere Position eines Listenelements. Mit welchem Element das ausgewählte Element verglichen wird, ist vom Sortierverfahren abhängig. In der inneren Schleife werden die Listenelemente miteinander verglichen. Wenn der Vorgänger größer ist als das ausgewählte Listenelement, dann werden die Positionen beider Elemente getauscht.

In Tabelle 14.1 werden beide Verfahren miteinander verglichen.

Bubble Sort

Selection Sort

for i in range(n-1):
for j in range(n-1):
if a[j]>a[j+1]:
a[j+1],a[j]=a[j],a[j+1]
print(i,j,a)
for i in range(n):
k=i
for j in range(i+1,n):
if a[j]<a[k]:
k=j
a[i],a[k] = a[k],a[i]
print(i,j,a)
        4   3   2   1
3 4 2 1
3 2 4 1
3 2 1 4
2 3 1 4
2 1 3 4
1 2 3 4
        4   3   2   1
3 4 2 1
2 4 3 1
1 4 3 2
1 3 4 2
1 2 4 3
1 2 3 4

Tabelle 14.1     Vergleich von Bubble Sort und Selection Sort

Listing 14.2 sortiert eine Zahlenfolge aus fünf ganzen Zahlen mit dem Bubble-Sort- und dem Selection-Sort-Verfahren in aufsteigender Reihenfolge.

Damit der Sortiervorgang deutlich wird, liegen die Zahlen in absteigender Reihenfolge vor (worst case). Der Sortierfortschritt wird während des Sortiervorgangs auf dem Bildschirm ausgegeben. Sie können die einzelnen Schritte also einzeln nachvollziehen und schauen, wie die Einträge verschoben werden.

01  #02_sortieren.py
02 def bubbleSort(a):
03 n=len(a)
04 for i in range(n-1):
05 for j in range(n-1):
06 if a[j]>a[j+1]:
07 a[j+1],a[j]=a[j],a[j+1]
08 print(i,j,a)
09
10 def selectionSort(a):
11 n=len(a)
12 for i in range(n):
13 k=i
14 for j in range(i+1,n):
15 if a[j]<a[k]:
16 k=j
17 a[i],a[k] = a[k],a[i]
18 print(i,j,a)
19 #return a
20 print("Bubble Sort")
21 x=[5,4,3,2,1]
22 print("i","j",x)
23 print("--------------------")
24 bubbleSort(x)
25 print("Selection Sort")
26 x=[5,4,3,2,1]
27 print("i","j",x)
28 print("--------------------")
29 selectionSort(x)

Listing 14.2     Elementare Sortieralgorithmen

Ausgabe
Bubble Sort
i j [5, 4, 3, 2, 1]
--------------------
0 0 [4, 5, 3, 2, 1]
0 1 [4, 3, 5, 2, 1]
0 2 [4, 3, 2, 5, 1]
0 3 [4, 3, 2, 1, 5]
1 0 [3, 4, 2, 1, 5]
1 1 [3, 2, 4, 1, 5]
1 2 [3, 2, 1, 4, 5]
2 0 [2, 3, 1, 4, 5]
2 1 [2, 1, 3, 4, 5]
3 0 [1, 2, 3, 4, 5]
Selection Sort
i j [5, 4, 3, 2, 1]
--------------------
0 1 [4, 5, 3, 2, 1]
0 2 [3, 5, 4, 2, 1]
0 3 [2, 5, 4, 3, 1]
0 4 [1, 5, 4, 3, 2]
1 2 [1, 4, 5, 3, 2]
1 3 [1, 3, 5, 4, 2]
1 4 [1, 2, 5, 4, 3]
2 3 [1, 2, 4, 5, 3]
2 4 [1, 2, 3, 5, 4]
3 4 [1, 2, 3, 4, 5]
Analyse

Im ungünstigsten Fall (engl. worst case) haben beide Algorithmen eine Laufzeitkomplexität von O(n2). Für die Berechnung des Medians wird Selection Sort ausgewählt, weil bei jedem Sortiervorgang in der inneren Schleife der Wert der Laufvariablen j um 1 verringert wird. Intuitiv scheint dieser Algorithmus »intelligenter« zu arbeiten.

Eine Python-Funktion als Modul importieren

Wählen Sie aus Listing 14.2 die Funktion selectionSort(a) aus, und speichern Sie die Datei unter dem Namen sortieren.py in dasselbe Verzeichnis. Jetzt können Sie die Funktion als Modul mit import sortieren as st in andere Programme importieren. Den Alias st können Sie natürlich frei wählen.

Listing 14.3 berechnet mit der importierten Python-Funktion den Median aus der Datei daten.txt. Wenn der Import auf Ihrem Rechner nicht funktionieren sollte, können Sie die Programmzeilen 03 und 06 auskommentieren oder löschen und den Kommentar in Zeile 07 entfernen. Zur Kontrolle wird das Ergebnis mit der NumPy- Funktion median(a) überprüft (Zeile 17).

01  #03_median.py
02 import numpy as np
03 import sortieren as st
04
05 def median(xu):
06 x=st.selectionSort(xu)
07 #x=np.sort(xu)
08 n=len(x)
09 if n%2!=0: #ungerade
10 return x[(n-1)//2]
11 else: #gerade
12 return (x[n//2-1]+x[n//2])/2
13 #Messwerte laden
14 a=np.loadtxt('daten.txt')
15 print("Median")
16 print(median(a))
17 print(np.median(a),"NumPy")

Listing 14.3     Berechnung des Medians

Ausgabe
Median
50.0
50.0 NumPy
Analyse

In Zeile 03 wird das selbst erstellte Modul sortieren mit der selbst erstellten Sortierfunktion selectionSort(...) aus Listing 14.2 importiert. Mit dem Alias st kann jetzt auf diese Sortierfunktion zugegriffen werden.

Die Funktionsdefinition für die Berechnung des Medians erfolgt in den Zeilen 05 bis 12. In Zeile 06 wird auf die selbst erstellte Funktion selectionSort(...) mit dem Alias st zugegriffen. Sollte das nicht funktionieren, können Sie die Zeile 06 löschen oder auskommentieren und den Kommentar in Zeile 07 entfernen. Dann sortiert die NumPy-Funktion sort() die Messwerte.

In Zeile 09 wird überprüft, ob die Anzahl der Messwerte ungerade ist. Wenn das der Fall ist, dann wird der in der Mitte stehende Messwert der sortierten Messreihe zurückgegeben (Zeile 10). Wenn die Anzahl der Messwert gerade ist, dann wird der Mittelwert aus den beiden mittleren Messwerten der sortierten Messreihe zurückgegeben (Zeile 12).

In Zeile 14 lädt die NumPy-Funktion loadtxt('daten.txt') die eintausend Messwerte. In Zeile 16 berechnet die selbst erstellte Funktion median(a) den Median dieser Messreihe. In Zeile 17 wird das Ergebnis mit der NumPy-Funktion median(a) kontrolliert.

14.2.3    Arithmetischer Mittelwert

Der arithmetische Mittelwert ist Ihnen wahrscheinlich noch aus der Schule bekannt, wenn der Notendurchschnitt einer Klassenarbeit berechnet werden musste. Die einzelnen Noten werden addiert und durch ihre Anzahl geteilt. Allgemein lautet die Berechnungsvorschrift:

formula

Anschaulich kann der arithmetische Mittelwert auch als Schwerpunkt des Flächeninhalts eines Histogramms interpretiert werden. Der arithmetische Mittelwert ist empfindlich gegenüber Ausreißern. Die Verpackungsanlage aus Abschnitt 14.1 sollte so eingestellt werden, dass das arithmetische Mittel möglichst nahe bei 50 g liegt.

Arithmetischer Mittelwert

Der arithmetische Mittelwert ist bildlich gesprochen der »Schwerpunkt« der Messwerte.

Listing 14.4 berechnet den arithmetischen Mittelwert mit dem Summenalgorithmus. Die Messwerte werden mit der NumPy-Funktion loadtxt('daten.txt') aus der Datei daten.txt geladen.

01  #04_arithmetischer_mittelwert.py
02 import numpy as np
03 def arithmetischM(x):
04 n=len(x)
05 summe=0
06 for i in range(n):
07 summe=summe+x[i]
08 return summe/n
09
10 a=np.loadtxt('daten.txt')
11 print("Arithmetischer Mittelwert")
12 print(arithmetischM(a))
13 print(np.mean(a),"NumPy")

Listing 14.4     Berechnung des arithmetischen Mittelwertes

Ausgabe

Arithmetischer Mittelwert
49.99859999999998
49.998599999999996 NumPy

Analyse

In Zeile 12 wird der arithmetische Mittelwert mit der von Ihnen erstellten Funktion arithmetischM(a) berechnet und ausgegeben. Die Überprüfung des Ergebnisses erfolgt in Zeile 13 mit der NumPy-Funktion mean(a).

14.2.4    Harmonischer Mittelwert

Der harmonische Mittelwert wird aus der Summe der Kehrwerte einer Messreihe berechnet. Anschließend wird von dieser Summe der Kehrwert gebildet, und diese Summe wird mit der Anzahl der Messwerte multipliziert. Die Berechnungsvorschrift lautet:

formula

Listing 14.5 berechnet die Summen der Kehrwerte von xi mit dem Summenalgorithmus aus den in der Datei daten.txt gespeicherten Messwerten. In der Praxis wird zwar die Genauigkeit einer Abfüllanlage nicht mit dem harmonischen Mittel überprüft, die Berechnung soll aber trotzdem an unserem Beispiel durchgeführt werden, um zu zeigen, wie dieser Algorithmus implementiert wird und in welcher Größenordnung das Ergebnis liegt.

01  #05_harmonischer_mittelwert.py
02 import numpy as np
03 from scipy.stats import hmean
04
05 def harmonischM(x):
06 n=len(x)
07 summe=0
08 for i in range(n):
09 summe=summe+1/x[i]
10 return n/summe
11
12 a=np.loadtxt('daten.txt')
13 print("Harmonischer Mittelwert")
14 print(harmonischM(a))
15 print(hmean(a),"SciPy")

Listing 14.5     Berechnung des harmonischen Mittelwertes

Ausgabe

Harmonischer Mittelwert
49.9789402828273
49.978940282827075 SciPy

Analyse

In Zeile 09 wird der Kehrwert 1/x[i] der einzelnen Messwerte aufsummiert. Bei der Rückgabe in Zeile 10 wird die Anzahl n der Messwerte durch diese Summe dividiert.

Der Vergleich mit der SciPy-Funktion hmean(a) (Zeile 15) zeigt eine Übereinstimmung des selbst programmierten Algorithmus von 12 Nachkommastellen.

14.2.5    Geometrischer Mittelwert

Bei der Berechnung des geometrischen Mittelwertes werden alle n Messwerte miteinander multipliziert, und anschließend wird aus diesem Produkt die n-te Wurzel gezogen:

formula

In der Formelsprache der Mathematik lautet die Berechnungsvorschrift abgekürzt:

formula

Bei unserem Erdnuss-Beispiel müssten eintausend Messwerte miteinander multipliziert werden. Wenn man näherungsweise annimmt, dass alle Faktoren den Wert 50 hätten, dann müsste das Programm 501000 berechnen und anschließend die 1000. Wurzel ziehen. Hiermit wäre wohl der leistungsfähigste Computer überfordert. Eine direkte Umsetzung in einen rekursiven Algorithmus formula würde also bei einer großen Anzahl von Messwerten zwangsläufig scheitern, wie der folgende Konsolendialog zeigt:

>>> (50**1000)**(1/1000)
Traceback (most recent call last):
File "<pyshell>", line 1, in <module>
OverflowError: int too large to convert to float

Um dieses Problem zu umgehen, wird aus jedem Messwert der Logarithmus gebildet, die einzelnen logarithmierten Werte werden mit dem Summenalgorithmus aufaddiert, und anschließend wird die Summe durch die Anzahl n dividiert. Zum Schluss wird das Logarithmieren mit der e-Funktion wieder rückgängig gemacht. Listing 14.6 zeigt die Umsetzung:

01  #06_geometrischer_mittelwert.py
02 import numpy as np
03 from scipy.stats import gmean
04
05 def geometrischM(x):
06 n=len(x)
07 s=0
08 for i in range(n):
09 s=s+np.log(x[i])
10 gm=s/n
11 return np.exp(gm)
12
13 a=np.loadtxt('daten.txt')
14 print("Geometrischer Mittelwert")
15 print(geometrischM(a))
16 print(gmean(a),"SciPy")

Listing 14.6     Berechnung des geometrischen Mittelwertes

Ausgabe

Geometrischer Mittelwert
49.98876495940364
49.98876495940464 SciPy

Analyse

In Zeile 09 werden die natürlichen Logarithmen log(x[i]) der einzelnen Messwerte zur Summe s aufsummiert. In Zeile 10 wird die Summe s durch die Anzahl n der Messwerte dividiert: gm=s/n. In Zeile 11 berechnet die NumPy-Funktion exp(gm) aus gm dann den geometrischen Mittelwert. Das Ergebnis stimmt mit dem von der SciPy-Funktion gmean(a) berechneten Wert überein.