python - tutorial - the django project
Biblioteca de corrección de línea de base de Python (2)
Encontré una respuesta a mi pregunta, simplemente compartiéndola para todos los que tropiezan con esto.
Hay un algoritmo llamado "Alisamiento de mínimos cuadrados asimétricos" por P. Eilers y H. Boelens en 2005. El documento es gratuito y puedes encontrarlo en google.
def baseline_als(y, lam, p, niter=10):
L = len(y)
D = sparse.csc_matrix(np.diff(np.eye(L), 2))
w = np.ones(L)
for i in xrange(niter):
W = sparse.spdiags(w, 0, L, L)
Z = W + lam * D.dot(D.transpose())
z = spsolve(Z, w*y)
w = p * (y > z) + (1-p) * (y < z)
return z
Actualmente estoy trabajando con algunos datos de Raman Spectra, y estoy tratando de corregir mis datos causados por el sesgo de la fluorescencia. Eche un vistazo al siguiente gráfico:
Estoy bastante cerca de lograr lo que quiero. Como pueden ver, estoy tratando de encajar un polinomio en todos mis datos mientras que realmente debería estar ajustando un polinomio en los minimas locales.
Idealmente, me gustaría tener un ajuste de polinomio que cuando se resta de mis datos originales resultaría en algo como esto:
¿Hay alguna biblioteca incorporada que hace esto ya?
Si no, ¿Algún algoritmo simple que uno pueda recomendarme?
Sé que esta es una vieja pregunta, pero me di cuenta de ello hace unos meses e implementé la respuesta equivalente usando rutinas spicy.sparse.
# Baseline removal
def baseline_als(y, lam, p, niter=10):
s = len(y)
# assemble difference matrix
D0 = sparse.eye( s )
d1 = [numpy.ones( s-1 ) * -2]
D1 = sparse.diags( d1, [-1] )
d2 = [ numpy.ones( s-2 ) * 1]
D2 = sparse.diags( d2, [-2] )
D = D0 + D2 + D1
w = np.ones( s )
for i in range( niter ):
W = sparse.diags( [w], [0] )
Z = W + lam*D.dot( D.transpose() )
z = spsolve( Z, w*y )
w = p * (y > z) + (1-p) * (y < z)
return z
Aclamaciones,
Pedro.