2014-11-14 28 views
8

Verilerime birden çok Gaussian bağlantı yapmanın bir yolunu arıyorum. Şimdiye kadar bulduğum örneklerin çoğu, rasgele sayılar yapmak için normal dağılımı kullanıyor. Ama verilerimin planına bakmak ve 1-3 zirve olup olmadığını kontrol etmek istiyorum.Python yük verileri ve çoklu Gaussian fit

Bunu bir tepe noktası için yapabilirim, ancak daha fazlasını nasıl yapacağımı bilmiyorum.

Örneğin, bu verilere sahip: Ben lmfit kullanarak denedi http://www.filedropper.com/data_11

ve tabii SciPy ki, ama hiçbir güzel sonuçlarla.

Yardımlarınız için teşekkürler!

+1

Sorunuz tamamen açık değil: (oldukça gürültülü) verilerinize bir Gauss aleti uydurmak ister misiniz? Maxima'nın yerini bulmak ister misiniz? Veriler 1-3 Gaussians'ın toplamı ve her birinin ortalama ve standart varyansını almak ister misiniz? –

+1

Merhaba! Cevap için teşekkürler :) Her bir zirve için bir Gauss takmak istiyorum. – astromath

+0

"Veriler 1-3 Gaussians'ın toplamıdır ve her birinin ortalama ve standart varyansını almak ister misiniz?" kesinlikle! – astromath

cevap

11

Tek Gaussians'ın toplamının parametreli model işlevlerini gerçekleştirin. İlk tahmininiz için iyi bir değer seçin (bu gerçekten kritik bir adımdır) ve daha sonra scipy.optimize bu sayıları biraz düzeltin. İşte

bunu nasıl açıklanmıştır:

import numpy as np 
import matplotlib.pyplot as plt 
from scipy import optimize 

data = np.genfromtxt('data.txt') 
def gaussian(x, height, center, width, offset): 
    return height*np.exp(-(x - center)**2/(2*width**2)) + offset 
def three_gaussians(x, h1, c1, w1, h2, c2, w2, h3, c3, w3, offset): 
    return (gaussian(x, h1, c1, w1, offset=0) + 
     gaussian(x, h2, c2, w2, offset=0) + 
     gaussian(x, h3, c3, w3, offset=0) + offset) 

def two_gaussians(x, h1, c1, w1, h2, c2, w2, offset): 
    return three_gaussians(x, h1, c1, w1, h2, c2, w2, 0,0,1, offset) 

errfunc3 = lambda p, x, y: (three_gaussians(x, *p) - y)**2 
errfunc2 = lambda p, x, y: (two_gaussians(x, *p) - y)**2 

guess3 = [0.49, 0.55, 0.01, 0.6, 0.61, 0.01, 1, 0.64, 0.01, 0] # I guess there are 3 peaks, 2 are clear, but between them there seems to be another one, based on the change in slope smoothness there 
guess2 = [0.49, 0.55, 0.01, 1, 0.64, 0.01, 0] # I removed the peak I'm not too sure about 
optim3, success = optimize.leastsq(errfunc3, guess3[:], args=(data[:,0], data[:,1])) 
optim2, success = optimize.leastsq(errfunc2, guess2[:], args=(data[:,0], data[:,1])) 
optim3 

plt.plot(data[:,0], data[:,1], lw=5, c='g', label='measurement') 
plt.plot(data[:,0], three_gaussians(data[:,0], *optim3), 
    lw=3, c='b', label='fit of 3 Gaussians') 
plt.plot(data[:,0], two_gaussians(data[:,0], *optim2), 
    lw=1, c='r', ls='--', label='fit of 2 Gaussians') 
plt.legend(loc='best') 
plt.savefig('result.png') 

result of fitting

Gördüğünüz gibi, bu iki uyan (görsel) arasında neredeyse hiçbir fark yoktur. 3,

err3 = np.sqrt(errfunc3(optim3, data[:,0], data[:,1])).sum() 
err2 = np.sqrt(errfunc2(optim2, data[:,0], data[:,1])).sum() 
print('Residual error when fitting 3 Gaussians: {}\n' 
    'Residual error when fitting 2 Gaussians: {}'.format(err3, err2)) 
# Residual error when fitting 3 Gaussians: 3.52000910965 
# Residual error when fitting 2 Gaussians: 3.82054499044 

Bu durumda: kaynağında mevcut veya sadece 2. Ancak 3 Gauss olsaydı bir tahmin yapmak zorunda Yani eğer en küçük kalıntı olup olmadığını kontrol sonra, kesin bilemeyiz Gaussyalılar daha iyi bir sonuç veriyor, ancak ilk tahminimi oldukça doğru bir şekilde yaptım.

+0

Merhaba.Onun cevabınız için çok teşekkür ederim.İki ayrı Gaussyalı almayı ve sonra onları birleştirmeyi denedim, ama çözümünüzü gördükten sonra yanlış bir fikir olduğunu anlıyorum. Lütfen bana "merkez" ve "ne olduğunu açıklar mısınız?" Ofset "parametreleri nelerdir? Yardımlarınız için çok teşekkür ederim! – astromath

+0

Bunlar, Gaussian'ın ve ona verilen dikey bir uzaklığın anlamı olabilir. Doğrulamak için 'Gaussian' tanımımı kontrol edin ;-) Stackoverflow'a Hoş Geldiniz. Size yardımcı olsaydı, [cevaplamadan veya cevabı kabul etmeyi] unutmayın (https://stackoverflow.com/help/someone-answers). –

+0

Merhaba Oliver! Tekrar teşekkürler:) Senaryoyu anlıyorum, ama '' ortalama '' Bunu nasıl tahmin ettiniz, ama daha basit ve hızlı bir şey yaptığınızı hissediyorum. Teşekkür ederim bir kez daha :) – astromath