Seite 1 von 1
levenberg marquardt :(
Verfasst: Dienstag 31. Januar 2012, 15:25
von Marie
Hallo alle zusammen,
hat eine von euch Ahnung, wie das Verfahren "levenberg marquardt "genau funktioniert. Ich hänge seit paar Tagen daran. Ich komme aber leider nicht wirklich voran. Kennt jmd eine implementation des Verfahrens in python? das würde mich viel helfen.
Leibe Grüße
Re: levenberg marquardt :(
Verfasst: Dienstag 31. Januar 2012, 15:50
von EyDu
Hallo.
Die Suche nach "levenberg marquardt python" liefert doch bereits eine Lösung mittels scipy. Außerdem stehen auf Wikipedia und Wolfram doch die entsprechende Formeln: eine eigene Umsetzung mit numpy ist dann doch trivial.
Sebastian
Re: levenberg marquardt :(
Verfasst: Dienstag 31. Januar 2012, 17:10
von Marie
Danke für die Tipps. Aber ich habe noch paar Schwierigkeiten. In Python bin ich nicht so gut.
ich habe eine gute Implementation in matlab gefunden, ich habe aber da eine Frage, nämlich wie kann man so eine funktion in python umschreiben: [alpha,beta,X2,y_hat,dydp] = lm_matx(func,t,p,y_dat,weight_sq,dp,c)?
Danke
LG
Re: levenberg marquardt :(
Verfasst: Dienstag 31. Januar 2012, 18:01
von EyDu
Hallo.
Eine Implementierung einer anderen Sprache S in Python P umschreiben kannst du, indem du jede Anweisung in S zu übersetzt, dass sie einer Anweisung in P entspricht. Das wird dir im Fall von Matlab aber wahrscheinlich recht wenig helfen, da du vermutlich nicht den Code besitzt. Für den Algorithmus muss man übrigens nicht mal besonders gut Python können. Eine Aufgae von vielleicht 10 Minuten.
Code: Alles auswählen
import numpy as np
def lma(fs, dfs, initial, lmbd, min_gain):
def error(x):
return 0.5*sum(f(x)**2 for f in fs)
def evalualte(x):
return np.matrix([[f(x)] for f in fs])
def jacobian(x):
return np.matrix([[f(x) for f in r] for r in dfs])
def step(x):
j = jacobian(x)
jtj = j.T*j
li = lmbd * np.identity(jtj.shape[0])
left = jtj+li
k = evalualte(x)
right = -j.T*k
return left.I*right
x = np.matrix(initial).T
gain = 2 * min_gain
new_error = None
while gain >= min_gain:
delta = step(x)
old_error = new_error
new_error = error(x)
x += delta
if old_error is not None:
gain = old_error - new_error
return x
def main():
f1 = lambda x: x[0,0]**2
f2 = lambda x: x[1,0]**2
f3 = lambda x: x[0,0]*x[1,0]
f1dx = lambda x: 2*x[0,0]
f1dy = lambda x: 0.0
f2dx = lambda x: 0.0
f2dy = lambda x: 2*x[1,0]
f3dx = lambda x: x[1,0]
f3dy = lambda x: x[0,0]
fs = [f1, f2, f3]
dfs = [[f1dx, f1dy], [f2dx, f2dy], [f3dx, f3dy]]
print lma(fs, dfs, (10.0, 20.0), 1.0, 0.00001)
if __name__ == "__main__":
main()
Die Wahl des damping-Parameters kann man natürlich noch optimieren.
Sebastian
Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 15:23
von Marie
Danke Sebastian für den Code *was ich leider nicht so ganz verstanden habe

*
Kannst Du mir vielleicht sagen warum ich dieser Fehler bekomme und wie ich dieser beheben kann.
Code: Alles auswählen
y_data = columns[1]
IndexError: list index out of range
Dr Code sieht so aus
Code: Alles auswählen
y_data = []
t = []
crs = open("Datei.txt", "r")
for columns in ( raw.strip().split() for raw in crs ):
y_data = columns[1]
t = columns[0]
data.append(y_data)
time.append(time)
Danke im Voraus
LG
Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 15:27
von Hyperion
Solche Fehler kannst Du einfach in einer Python-Shell versuchen, nachzuvollziehen. Lass Dir doch mal direkt nach der Schleife ``columns`` ausgeben - dann erkennst Du sicher sofort, wieso der Fehler kommt.
Generell sieht der Code ein wenig umständlich aus. Zudem taucht ``time`` nirgends auf - Du bekommst dann den nächsten Fehler, sobald der erste behoben ist.
Wieso willst Du Dir offenbar zusammenhängende Daten in zwei separaten Objekten merken?
Evtl. kann Dir beim Einlesen auch das ``csv``-Modul Hilfe leisten.
Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 15:34
von Marie
Ich konnte leider den Fehler nicht finden

Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 15:50
von Hyperion
Du kannst den Fehler ja auch so im Script finden - du musst da ja nur ein ``print`` Statement einfügen.
Der Hinweis auf eine Shell brachte ich deswegen, damit Du Konstrukte, wie
Code: Alles auswählen
for columns in ( raw.strip().split() for raw in crs ):
...
eben erst einmal separat testest, bevor Du so etwas in ein Script einbaust. So etwas hilft doch enorm
Dateien solltest Du übrigens so öffnen:
Code: Alles auswählen
with open(...) as handler:
# handler ist hier File-Object
# es wird nach Durchlaufen des Blocks automatisch geschlossen
Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 15:51
von Hyperion
Marie hat geschrieben:Ich konnte leider den Fehler nicht finden

Poste doch mal die komplette Ausgabe.
Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 15:56
von Marie
Hyperion hat geschrieben:Marie hat geschrieben:Ich konnte leider den Fehler nicht finden

Poste doch mal die komplette Ausgabe.
Ausgabe
Code: Alles auswählen
0.1837
-1.6762
-1.7639
0.3118
4.0473
8.4418
12.4349
15.0443
15.4261
13.2425
9.1291
4.5988
1.2063
-0.3603
-0.4915
-0.0904
0.1993
0.3526
0.7231
1.4638
2.0657
1.4138
-1.5479
-6.9588
-13.6981
-19.8780
-23.7647
-24.4734
-22.1911
-18.0425
-13.6499
-10.4237
-8.9728
-9.1255
-10.4815
-12.8756
-16.3304
-20.6567
-25.1772
-28.9096
-31.0687
-31.4088
-30.2043
Traceback (most recent call last):
File "/home/CurveFiting/src/Read.py", line 29, in <module>
data_load = columns[3]
IndexError: list index out of range
Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 16:06
von Hyperion
Deine Fehlermeldung passt nicht zum oben geposteten Quellcode - wie sollen wir Dich da auf die richtige Fährte bringen?
Ich werde es Dir dennoch mal an einem Beispiel demonstrieren:
Code: Alles auswählen
>>> data = """1 eins
... 2 zwei
... 3
... 4 vier"""
>>>
>>> for line in data.split("\n"):
... print(line)
...
1 eins
2 zwei
3
4 vier
>>> for line in data.split("\n"):
... print(line.split())
...
['1', 'eins']
['2', 'zwei']
['3']
['4', 'vier']
>>> for line in data.split("\n"):
... print(line.split()[1])
...
eins
zwei
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
IndexError: list index out of range
Na, was fällt Dir auf?
Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 16:28
von Marie
mir fehlt auf, dass bei print line, die data so ausgegeben uwrde wie sie in der Datei steht zeilenweise.
dann mit print (line.split()) wurde die Element jeder Zeile in einem Array gespeichert und ausgegeben.
Dann mit print (line.split()[1]) sind nur eins, zqei ausgegeben wurden. D,h, zweiter Element in erster Zeile und zweiter Element in der zweiten Zeile. ???
Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 16:32
von Hyperion
Man sagt dazu in Python nicht ``array``, sondern Liste bzw. ``list``. Ansonsten hast Du das zwar alles verstanden, aber nicht den Kern des Problems. Nämlich, wieso es zu dem Fehler kommt an genau der Stelle. Ich geb Dir noch mal nen Tipp: Wenn in Zeile drei nicht nur "3" sondern z.B. "3 drei" stünde, gäbe es keinen Fehler. Kannst das ja mal in einer Shell ausprobieren.
Also so langsam solltest Du doch kapieren, was es mit diesem ``IndexError`` auf sich hat...
Re: levenberg marquardt :(
Verfasst: Donnerstag 2. Februar 2012, 16:50
von Marie
Danke.