Как я могу улучшить гауссово / нормальное соответствие в Python 3.X, используя текущую медиану? - PullRequest
0 голосов
/ 12 июня 2018

У меня есть массив точек данных 100x100, где я пытаюсь выполнить гауссову подгонку к каждому столбцу из 100 значений в массиве.Затем я хочу, чтобы параметры гауссиана, найденные с использованием подгонки первого столбца, были начальными параметрами начальной точки для следующего столбца.Допустим, я начинаю с начальных параметров 1000, 0 и 1, и подгонка находит значения 800, 3 и 1,5.Затем я хочу, чтобы установщик использовал эти три параметра в качестве начальных значений для следующего столбца.

Мой код:

x = np.linspace(-50,50,100)
Gauss_Model = models.Gaussian1D(amplitude = 1000., mean = 0, stddev = 1.)
Fitting_Model = fitting.LevMarLSQFitter()

Fit_Data = []

for i in range(0, Data_Array.shape[0]):
    Fit_Data.append(Fitting_Model(Gauss_Model, x, Data_Array[:,i]))

Сейчас он использует одни и те же начальные значения для каждой подгонки.Кто-нибудь знает, как выполнить такую ​​бегущую медиану / среднее для метода гауссовой подгонки?Буду очень признателен за любую помощь или указали в правильном направлении, спасибо!

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Я также не могу сказать, какую библиотеку вы используете, и детали того, как это сделать, вероятно, зависят от деталей того, как эта библиотека хранит подогнанные значения.Я могу сказать, что для lmfit (https://lmfit.github.io/lmfit-py/) мы боролись с такого рода использованием и пришли к дизайну, который делает то, что вы пытаетесь сделать, довольно простым. С lmfit вы можете решить эту проблему следующим образом:

import numpy as np
from lmfit import GaussianModel

x = np.linspace(-50,50,100)
# get Data_Array from somewhere....

# create a model for a Gaussian
Gauss_Model = GaussianModel()

# make a set of parameters, setting initial values
params = Gauss_Model.make_params(amplitude=1000, center=0, sigma=1.0)

Fit_Results = []

for i in range(Data_Array.shape[1]):
    result = Gauss_Model.fit(Data_Array[:, i], params, x=x)
    Fit_Results.append(result)
    # update `params` with the current best fit params for the next column
    params = result.params

Обратите внимание, что это работает, потому что lmfit тщательно следит за тем, чтобы Model.fit() не изменил входные параметры и поместил результирующие параметры наилучшего соответствия для каждого соответствия в result.params.

И, еслиВы решаете, что хотите, чтобы все столбцы использовали исходные начальные значения, просто закомментируйте, что в последнем params = result.params.

Lmfit гораздо больше наворотов, но я надеюсь, что это поможет вам сделать то, что вам нужно.

0 голосов
/ 12 июня 2018

Я не знаком с конкретной библиотекой, которую вы используете, но если вы можете получить свои подогнанные параметры с помощью чего-то вроде fit_data[-1].amplitude или fit_data[-1].mean, то вы можете изменить свой цикл, чтобы использовать что-то вроде:

for i in range(0, data_array.shape[0]):
    if fit_data:  # true if not an empty list
        Gauss_Model = models.Gaussian1D(amplitude=fit_data[-1].amplitude,
                                        mean=fit_data[-1].mean,
                                        stddev=fit_data[-1].stddev)
    fit_data.append(Fitting_Model(Gauss_Model, x, Data_Array[:,i]))

в основном проверяет, подходит ли вам уже модель, и, если она у вас есть, используйте самую последнюю установленную амплитуду, среднее значение и стандартное отклонение в качестве отправной точки для следующих Gauss_Model.

Мысль: это может ускорить процесс подгонки, но это не должно привести к «лучшему» подгонке к 100 точкам данных в каждой операции подбора.Ваша получающаяся модель, вероятно, является лучшей моделью, подходящей для данных, которые она представила.Если вы хотите оценить ошибку в параметрах вашей модели, вы можете использовать тот факт, что для двух нормальных распределений A ~ N(m_a, v_a) и B ~ N(m_b, v_b) распределение A + B будет иметь среднее значение m_a + m_bи дисперсия v_a + v_b.Таким образом, распределение ваших означает будет N(sum(means)/n, sum(variances)/n).По сути, вы можете сказать, что ваше истинное среднее значение центрировано по среднему значению ваших значений со стандартным отклонением (sum(stddev)/sqrt(n)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...