Sto provando a fare un adattamento gaussiano su molti punti dati. Per esempio. Ho una matrice di dati 256 x 262144. Dove i 256 punti devono essere adattati a una distribuzione gaussiana, e ho bisogno di 262144 di essi.Come posso eseguire un montaggio dei minimi quadrati su più set di dati velocemente?
A volte il picco della distribuzione gaussiana si trova al di fuori dell'intervallo di dati, quindi per ottenere un risultato medio accurato l'adattamento della curva rappresenta l'approccio migliore. Anche se il picco si trova all'interno dell'intervallo, l'adattamento della curva fornisce un sigma migliore perché altri dati non sono compresi nell'intervallo.
Ho questo funzionamento per un punto di dati, utilizzando il codice da http://www.scipy.org/Cookbook/FittingData.
Ho provato a ripetere questo algoritmo, ma sembra che occorrerà qualcosa nell'ordine di 43 minuti per risolvere questo problema. C'è un modo veloce già scritto per farlo in parallelo o in modo più efficiente?
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
Si noti che i dati non sono necessariamente 256x262144 e ho fatto qualche giro in fudging nd_fit per fare questo lavoro.
Il codice che uso per ottenere questo al lavoro è
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)
Nota: La soluzione postato qui sotto per @JoeKington è grande e risolve veramente veloce. Tuttavia, non sembra funzionare a meno che l'area significativa del gaussiano sia all'interno dell'area appropriata. Dovrò verificare se la media è ancora precisa, dato che questa è la cosa principale per cui la uso.
Potresti pubblicare il codice che hai utilizzato? –