Подгонка данных с несколькими гауссовыми профилями в Python

У меня есть некоторые данные (data.txt), и я пытаюсь написать код на Python, чтобы по-разному совмещать их с гауссовыми профилями, чтобы в каждом случае получать и сравнивать разделение пиков и площадь под кривой:

  1. с двумя гауссовыми профилями (учитывая маленькие пики сверху и игнорируя плечи; красные профили)
  2. с двумя гауссовыми профилями (игнорируя маленькие пики сверху и учитывая весь одиночный пик сверху и плечами; черные профили)
  3. с тремя гауссовыми профилями (учитывая высокую вершину на двух более коротких в плечах; зеленые профили)

Я перепробовал несколько сценариев, но потерпел неудачу во всех.

Профили на этих графиках являются поддельными, и я просто добавил их, чтобы лучше проиллюстрировать, что я имею в виду.

1 ответ

Один из подходов к этому заключается в следующем:

  1. Определите функцию, которую вы хотите вписать в данные, т.е. сумму всех компонентов, которые должны быть там. В вашем случае это несколько гауссиан.
  2. Найдите начальные догадки для ваших параметров.
  3. Подгоните свою функцию подгонки к данным, используя стратегию по своему вкусу.

Я ознакомился с вашими данными, и ниже приведен очень простой пример подгонки трех гауссовых компонентов и смещения континуума с использованием SciPy. curve_fit метод. Я оставлю тебе остальное. Это должно позволить вам выяснить и другие случаи. Обратите внимание, что первоначальные предположения, как правило, важны, поэтому лучше сделать обоснованное предположение, чтобы максимально приблизиться к оптимальному значению.

Код

from scipy.optimize import curve_fit

import matplotlib.pyplot as plt
import numpy as np

def gaussian(x, A, x0, sig):
    return A*np.exp(-(x-x0)**2/(2*sig**2))

def multi_gaussian(x, *pars):
    offset = pars[-1]
    g1 = gaussian(x, pars[0], pars[1], pars[2])
    g2 = gaussian(x, pars[3], pars[4], pars[5])
    g3 = gaussian(x, pars[6], pars[7], pars[8])
    return g1 + g2 + g3 + offset

vel, flux = np.loadtxt('data.txt', unpack=True)
# Initial guesses for the parameters to fit:
# 3 amplitudes, means and standard deviations plus a continuum offset.
guess = [4, -50, 10, 4, 50, 10, 7, 0, 50, 1]
popt, pcov = curve_fit(multi_gaussian, vel, flux, guess)

plt.figure()
plt.plot(vel, flux, '-', linewidth=4, label='Data')
plt.plot(vel, multi_gaussian(vel, *popt), 'r--', linewidth=2, label='Fit')
plt.legend()
plt.show()

Результат

Scikit -learn имеет реализацию GaussianMixtureModel, он может это делать. Смотрите инструкцию для примеров.

Другие вопросы по тегам