Hallo,
ich versuche ein Programm zu schreiben, um nach dem Maximum-Likelihood-Verfahren einen Parameter zu schätzen (hier soll es der Mittelwert einer normalverteilten Größe sein). Das Programm möchte ich möglichst flexibel und elegant schreiben. Am Anfang möchte ich gefragt werden, wie viele Stichproben genommen werden sollen. Als Anwendungsbeispiel habe ich eine Getränkeabfüllanlage im Kopf. Wähle ich n Stichproben, generiert mir das Programm n Zufallswerte, die um beispielsweise 0,5 verteilt sind. Idee war nun, dass mir das Programm n Stichprobenwerte in eine Liste schreibt, mit der ich dann im weiteren Verlauf des Programms weiterarbeite. Problem: Im Moment schaffe ich es nicht, die Zufallszahlen in eine Liste schreiben zu lassen. Ich hab mir überlegt, dass ich mit einer for-Schleife arbeite, die mir nach jedem Durchlauf den jeweils generierten Wert in eine zunächst leere Liste schreibt.
Vielleicht hat hier jemand hilfreiche Tipps oder Programmbeispiele.
Danke schon mal!
Anmerkung:
Wie ich mir das vorstelle, wenn beispielsweise 3 Stichproben genommen werden:
Durchlauf 0: liste = []
Durchlauf 1: Stichprobe 490 wurde generiert --> liste = [490]
Durchlauf 2: Stichprobe 510 wurde generiert --> liste = [490, 510]
Durchlauf 3: Stichprobe 500 wurde generiert --> liste = [490, 510, 500]
Zufallszahlen in Liste schreiben
@Kurtosis: Warum machst Du das was Du Dir überlegt hast nicht einfach mal? Das ist doch schneller als hier zu fragen.
Statt einer Schleife die eine leere Liste befüllt, könnte man eine „list comprehension” verwenden.
Statt einer Schleife die eine leere Liste befüllt, könnte man eine „list comprehension” verwenden.
Ich probiere auch die ganze Zeit schon daran rum, aber bisher es hat es noch nicht geklappt. Bin gerade aber einen großen Schritt weiter gekommen. Wenn ich das gewünschte Ergebnis erzielt habe, poste ich mal, was ich da programmiert habe, falls da Interesse besteht.
- pillmuncher
- User
- Beiträge: 1528
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
@Kurtosis: Und wie?
In specifications, Murphy's Law supersedes Ohm's.
So, Programm ist nun fertig und berechnet Mittelwert, Varianz und Standardabweichung der Stichproben, ohne dabei vorgefertigte Funktionen, die direkt den Mittelwert berechnen würden, zu verwenden. Das Problem im Eingangsposting habe ich wie folgt gelöst:
Code: Alles auswählen
liste1 = list()
def Stichproben(n):
for i in range(0,n):
a = random.randint(490,510)
b = liste1.append(a)
Zuletzt geändert von Kurtosis am Dienstag 2. Juli 2013, 15:16, insgesamt 4-mal geändert.
@Kurtosis: Die Funktion führt zu einem `NameError` weil `liste1` nicht definiert ist. Wobei ich mich auch Frage was die 1 in dem Namen zu suchen hat, denn es gibt in der Funktion ja nur eine Liste (wenn man sie denn mal definieren würde) und Namen durchnummerieren ist in der aller Regel sowieso ein Zeichen, dass man etwas falsch macht. Entweder schlechte Namen oder falsche Datenstruktur.
`b` macht keinen Sinn weil der Wert 1. sinnlos ist und 2. überhaupt nicht verwendet wird.
`b` macht keinen Sinn weil der Wert 1. sinnlos ist und 2. überhaupt nicht verwendet wird.
Hab oben noch ein paar Verbesserungen vorgenommen. Ich probiere ja noch rum, deswegen mag die erste Version vielleicht noch nicht super elegant sein. Tatsache ist aber, dass das Programm macht, was es tun soll, und mir grundsätzlich klar ist, was in welcher Zeile passiert. Das die eine oder andere Programmzeile noch nicht optimal ist, mag sein.
Das ist ein sehr ausführlicher (und umständlicher Code). Zudem sollte man liste1 innerhalb der Funktion definieren, abgesehen davon, dass es meist eher sinnlos/unklug ist, den Datentyp direkt im Bezeichnernamen anzugeben.Kurtosis hat geschrieben:Code: Alles auswählen
liste1 = list() def Stichproben(n): for i in range(0,n): a = random.randint(490,510) b = liste1.append(a) return liste1
Unter Verwendung einer List Comprehension lässt sich der ganze Code wie folgt eindampfen:
Code: Alles auswählen
def strichproben(n):
return [random.randint(490, 510) for _ in xrange(n)]
- pillmuncher
- User
- Beiträge: 1528
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
@Kurtosis: Naja. Daran gibt es einiges zu verbessern. Warum ist liste1 keine lokale Variable der Funktion Stichproben()?Man könnte übrigens einfach [] statt list() schreiben:b ist immer None, da die Listenmethode append() eben immer None zurückgibt. Also:Die Variable a braucht man eigentlich auch nicht:Der Abstand von 1 zu n + 1 ist derselbe wie von 0 zu n. Die range()-Funktion startet immer bei 0, falls kein anderer Startwert angegeben wird:Nun kann man aus der for-Schleife auch eine List Comprehension machen:Damit brauchen wir auch liste1 nicht mehr:Nun würde ich noch vorschlagen, sich an PEP8 zu halten und den Funktionsnamen klein zu schreiben, oder sogar die Funktion einfach wegzulassen und die List Comprehension direkt zu verwenden. Als statt etwa:zu schreiben:. Und falls du Python 2.x verwendest, würde ich hier statt range() die Funktion xrange() verwenden:
Code: Alles auswählen
def Stichproben(n):
liste1 = list()
for i in range(1, n + 1):
a = random.randint(490, 510)
b = liste1.append(a)
return liste1
Code: Alles auswählen
def Stichproben(n):
liste1 = []
for i in range(1, n + 1):
a = random.randint(490, 510)
liste1.append(a)
return liste1
Code: Alles auswählen
def Stichproben(n):
liste1 = []
for i in range(1, n + 1):
a = random.randint(490, 510)
liste1.append(a)
return liste1
Code: Alles auswählen
def Stichproben(n):
liste1 = []
for i in range(1, n + 1):
liste1.append(random.randint(490, 510))
return liste1
Code: Alles auswählen
def Stichproben(n):
liste1 = []
for i in range(n):
liste1.append(random.randint(490, 510))
return liste1
Code: Alles auswählen
def Stichproben(n):
liste1 = [random.randint(490, 510) for i in range(n)]
return liste1
Code: Alles auswählen
def Stichproben(n):
return [random.randint(490, 510) for i in range(n)]
Code: Alles auswählen
result = Stichproben(some_number)
Code: Alles auswählen
result = [random.randint(490, 510) for i in range(some_number)]
Code: Alles auswählen
result = [random.randint(490, 510) for i in xrange(some_number)]
In specifications, Murphy's Law supersedes Ohm's.
Danke euch! Ich werde mir eure Anmerkungen mal klarmachen und dann entsprechend berücksichtigen. Da Programmierung kein elementarer Bestandteil meines Studiums ist und ich mich aus Zeitgründen nicht jeden Tag damit beschäftigen kann, bin ich halt noch ein Python-Amateur. Mein Code mag vielleicht umständlich sein, aber ich verstehe so leichter, was im Programm eigentlich passiert, da halt nicht mehrere Sachen gleichzeitig in einer Zeile passieren. Aber danke für eure Tipps!
Ich habe jetzt noch ein paar Verbesserungen vorgenommen.
Code: Alles auswählen
# Zusatzpakete
import random
# Funktionen
def start():
print "########################################"
print "### Maximum-Likelihood-Verfahren ###"
print "### Normalverteilung ###"
print "########################################"
print ""
def anfangsbedingungen():
print "Wie groß ist der Umfang der Stichproben?"
n = input("Umfang der Stichproben: ")
print "Welchen Wert hätte die optimale Stichprobe?"
mu = input("Optimale Stichprobe: ")
sigma = random.uniform(0,0.02*mu)
return n,mu,sigma
def stichproben(n,mu,sigma):
return [round(random.normalvariate(mu,sigma),2) for i in xrange(n)]
def stichprobenprotokoll(liste1):
print ""
print "Stichprobenprotokoll:"
print liste1
def mittelwert(liste1,n):
summe = sum(liste1)
mittelwert = round(summe*1./n,2)
print ""
print "Mittelwert der Stichproben:", mittelwert
return mittelwert
def varianz(liste1,mittelwert,n):
liste2 = [(liste1[i] - mittelwert)**2 for i in xrange(n)]
varianz = round(sum(liste2)*1./n,2)
standardabweichung = round((sum(liste2)*1./n)**(1./2),2)
print "Varianz der Stichproben:", varianz
print "Standardabweichung der Stichproben:", standardabweichung
# Programm
start()
n,mu,sigma = anfangsbedingungen()
liste1 = stichproben(n,mu,sigma)
stichprobenprotokoll(liste1)
mittelwert = mittelwert(liste1,n)
varianz(liste1,mittelwert,n)
@Kurtosis: den Mittelwert zu runden und dann damit weiterzurechnen ist vielleicht nicht die beste Idee. Wenn es Dir nur darum geht, die Ausgabe schön zu haben, bieten sich Formatierungen an:
In »varianz« die Summe zweimal auszurechnen ist dann auch unnötig. Die Anzahl der Elemente weißt Du schon aus der Länge der Liste, muß also nicht extra mitgegeben werden. For-Schleifen in Python gehen über alle Elemente einer Liste. Wenn Du also eine for-Schleife über alle Indizes einer Liste machst um danach die Listenelemente über den Index anzusprechen drehst Du Dich wieder dreimal im Kreis:
Code: Alles auswählen
print "Mittelwert: {:.2f}".format(mittelwert)
Code: Alles auswählen
def varianz(liste1, mittelwert):
varianz = sum((wert - mittelwert)**2 for wert in liste1)/float(len(liste1))
standardabweichung = varianz**0.5
print "Varianz der Stichproben: {:.2f}".format(varianz)
print "Standardabweichung der Stichproben: {:.2f}".format(standardabweichung)
-
- User
- Beiträge: 25
- Registriert: Freitag 12. April 2013, 19:53
@Kurtosis:
Wenn ich mir dein Programm anschaue erzeugst du nur Zahlen im Bereich +/- Sigma um den Mittelwert. Das entspricht aber nur 68,27% aller Stichproben bei einer Normalverteilung. Ohne jetzt deinen Verwendungszweck genau zu kennen, müsste die Verteilung eigentlich von - unendlich bis + unendlich stattfinden.
Wenn ich mir dein Programm anschaue erzeugst du nur Zahlen im Bereich +/- Sigma um den Mittelwert. Das entspricht aber nur 68,27% aller Stichproben bei einer Normalverteilung. Ohne jetzt deinen Verwendungszweck genau zu kennen, müsste die Verteilung eigentlich von - unendlich bis + unendlich stattfinden.