Próbuję dopasować gaussa do wielu punktów danych. Na przykład. Mam tablicę danych 256 x 262144. Gdzie 256 punktów należy dopasować do rozkładu gaussowskiego i potrzebuję ich 262144.Jak szybko wykonać dopasowanie najmniejszych kwadratów na wielu zestawach danych?
Czasami szczyt rozkładu gaussowskiego znajduje się poza zakresem danych, więc aby uzyskać dokładny średni wynik, dopasowanie krzywej jest najlepszym podejściem. Nawet jeśli szczyt znajduje się w zakresie, dopasowywanie krzywej daje lepszą sigmę, ponieważ inne dane nie mieszczą się w zakresie.
Mam to działa dla jednego punktu danych, przy użyciu kodu z http://www.scipy.org/Cookbook/FittingData.
Próbowałem po prostu powtórzyć ten algorytm, ale wygląda na to, że zajmie to około 43 minut, aby rozwiązać ten problem. Czy istnieje już napisany szybki sposób robienia tego równolegle lub bardziej efektywnie?
from scipy import optimize
from numpy import *
import numpy
# Fitting code taken from: http://www.scipy.org/Cookbook/FittingData
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])
i += 1
return y - function(x)
if x is None: x = arange(y.shape[0])
p = [param() for param in parameters]
optimize.leastsq(f, p)
def nd_fit(function, parameters, y, x = None, axis=0):
"""
Tries to an n-dimensional array to the data as though each point is a new dataset valid across the appropriate axis.
"""
y = y.swapaxes(0, axis)
shape = y.shape
axis_of_interest_len = shape[0]
prod = numpy.array(shape[1:]).prod()
y = y.reshape(axis_of_interest_len, prod)
params = numpy.zeros([len(parameters), prod])
for i in range(prod):
print "at %d of %d"%(i, prod)
fit(function, parameters, y[:,i], x)
for p in range(len(parameters)):
params[p, i] = parameters[p]()
shape[0] = len(parameters)
params = params.reshape(shape)
return params
Należy pamiętać, że dane niekoniecznie są 256x262144 i zrobiłem trochę fudging w nd_fit, aby to działało.
Kod używam uzyskać to do pracy jest
from curve_fitting import *
import numpy
frames = numpy.load("data.npy")
y = frames[:,0,0,20,40]
x = range(0, 512, 2)
mu = Parameter(x[argmax(y)])
height = Parameter(max(y))
sigma = Parameter(50)
def f(x): return height() * exp (-((x - mu())/sigma()) ** 2)
ls_data = nd_fit(f, [mu, sigma, height], frames, x, 0)
Uwaga: Rozwiązanie pisał poniżej @JoeKington jest wielki i rozwiązuje bardzo szybko. Jednak wydaje się, że nie działa, chyba że znaczna część gaussa znajduje się w odpowiednim obszarze. Będę musiał sprawdzić, czy średnia jest nadal dokładna, ponieważ to jest główna rzecz, której używam.
Czy możesz wpisać kod, którego używałeś? –