Code explanation fit mithilfe einer Klasse

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Neuron23
User
Beiträge: 8
Registriert: Mittwoch 19. Juli 2017, 13:32

Könnte mir bitte jemand diesen Code erklären ?
import numpy as np
from scipy import optimize

class Parameter:
def __init__(self, value):
self.value = value

def set(self, value):
self.value = value

def __call__(self):
return self.value

def fit(function, parameters, y, x = None):
def f(params):
i = 0
for p in parameters:
p.set(params)
i += 1
return y - function(x)

if x is None: x = np.arange(y.shape[0])
p = [param() for param in parameters]
return optimize.leastsq(f, p)

So wird er dann aufgerufen ;

# giving initial parameters
mu = Parameter(7)
sigma = Parameter(3)
height = Parameter(5)

# define your function:
def f(x): return height() * np.exp(-((x-mu())/sigma())**2)

# fit! (given that data is an array with the data to fit)
data = 10*np.exp(-np.linspace(0, 10, 100)**2) + np.random.rand(100)
print fit(f, [mu, sigma, height], data)

Wie Klassen funktionieren verstehe ich im Allgemeinen.
Was ich nicht verstehe sind die Schleifen mit den params und warum f(params)
Die Parameter werden ja als Objekte verwendet , die dann zum optimalen Fitten der Funktion angewendet werden sollen .
Wäre toll, wenn mir jemand helfen könnte !
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie soll man etwas erklären, was so umständlich gemacht wurde, dass man das niemals so schreiben würde?
In Python benutzt man keine Setter sondern würde values direkt setzen. Globale Variablen sollte man nicht benutzen, mu, sigma und height sollten direkt an die zu fittende Funktion übergeben werden. Damit wird auch die komplette Parameter-Klasse und die Schleife überflüssig.

Korrekt sieht der Fit also so aus:

Code: Alles auswählen

import numpy as np
from scipy import optimize

def fit(function, parameters, y, x=None):
    def f(params):
        return y - function(x, *params)
    if x is None:
        x = np.arange(y.shape[0])
    return optimize.leastsq(f, parameters)

# define your function:
def gauss(x, mu, sigma, height):
    return height * np.exp(-((x-mu)/sigma)**2)

# fit! (given that data is an array with the data to fit)
data = 10*np.exp(-np.linspace(0, 10, 100)**2) + np.random.rand(100)
# giving initial parameters
mu = 7
sigma = 3
height = 5
print fit(gauss, [mu, sigma, height], data)
`leastsq` erwartet als Parameter eine Funktion `f`, die die Fit-Parameter (hier mu, sigma und height) als Argument bekommt und den Abstand zu den Soll-Werten zurückliefert, also die Differenz zwischen Soll-Werten und des Gauss, den Du mit den Fit-Parametern berechnest.
Neuron23
User
Beiträge: 8
Registriert: Mittwoch 19. Juli 2017, 13:32

Danke für die Antwort!
Was bedeutet jetzt in diesem Zusammenhang noch (x,*params)?
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Das Sternchen in *params bedeutet Parameter-unpacking, also die Listeneinträge in params werden an die Funktion einzeln als Argumente übergeben.
Antworten