2014-11-14 15 views
8

Tôi đã tìm cách làm nhiều Gaussian phù hợp với dữ liệu của mình. Hầu hết các ví dụ tôi đã tìm thấy cho đến nay sử dụng phân phối bình thường để tạo ra các số ngẫu nhiên. Nhưng tôi quan tâm đến việc xem xét cốt truyện của dữ liệu của tôi và kiểm tra nếu có 1-3 đỉnh.Dữ liệu tải Python và thực hiện nhiều kiểu Gaussian phù hợp

Tôi có thể làm điều này cho một điểm cao nhất, nhưng tôi không biết cách làm điều đó để biết thêm.

Ví dụ, tôi có dữ liệu này: http://www.filedropper.com/data_11

Tôi đã cố gắng sử dụng lmfit, và tất nhiên scipy, nhưng không có kết quả tốt đẹp.

Cảm ơn bạn đã trợ giúp!

+1

Câu hỏi của bạn không hoàn toàn rõ ràng: bạn có muốn phù hợp với Gaussian với dữ liệu của bạn (thay vì ồn ào) không? Bạn có muốn tìm vị trí của maxima không? Dữ liệu có tổng cộng 1-3 Gaussians và bạn muốn lấy phương sai trung bình và chuẩn của mỗi nhóm không? –

+1

Xin chào! Cảm ơn bạn đã trả lời :) Tôi muốn phù hợp với một Gaussian cho mỗi đỉnh. – astromath

+0

"Dữ liệu có tổng cộng 1-3 Gaussians và bạn muốn lấy phương sai trung bình và chuẩn của mỗi?" chính xác! – astromath

Trả lời

11

Chỉ cần thực hiện các chức năng mô hình được tham số hóa của tổng số Gaussians đơn. Chọn một giá trị tốt cho đoán ban đầu của bạn (đây là một bước thực sự quan trọng) và sau đó có scipy.optimize tinh chỉnh các số đó một chút.

Đây là cách bạn có thể làm điều đó:

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

Như bạn có thể thấy, hầu như không có sự khác biệt giữa hai phù hợp này (trực quan). Vì vậy, bạn không thể biết chắc chắn nếu có 3 Gaussians có mặt trong nguồn hoặc chỉ 2. Tuy nhiên, nếu bạn phải đoán, sau đó kiểm tra số dư nhỏ nhất:

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 

Trong trường hợp này, 3 Gaussians cho kết quả tốt hơn, nhưng tôi cũng đã đoán ban đầu của tôi khá chính xác.

+0

Xin chào.Cảm ơn bạn rất nhiều vì câu trả lời của bạn. Tôi đã cố gắng lấy hai Gaussians riêng biệt và sau đó kết hợp chúng, nhưng tôi hiểu đó là một ý tưởng sai sau khi tôi thấy giải pháp của bạn. Bạn có thể giải thích cho tôi những gì "trung tâm" và " bù đắp "tham số được? Cảm ơn bạn rất nhiều vì đã giúp đỡ của bạn! – astromath

+0

Đó sẽ là giá trị trung bình của Gaussian và giá trị bù dọc được gán cho nó. Kiểm tra định nghĩa của tôi 'Gaussian' để xác minh ;-) Chào mừng bạn đến Stackoverflow. Đừng quên [upvote hoặc chấp nhận câu trả lời] (https://stackoverflow.com/help/someone-answers) nếu nó giúp bạn. –

+0

Xin chào Oliver! Cảm ơn bạn một lần nữa:) Tôi hiểu kịch bản, nhưng làm thế nào bạn đoán '' có nghĩa là tôi sẽ sử dụng numpy cho điều đó, nhưng tôi cảm thấy rằng có một cái gì đó đơn giản hơn và nhanh hơn mà bạn đã làm. Cảm ơn bạn một lần nữa :) – astromath

Các vấn đề liên quan