Как подогнать функцию без подгонки интересующей функции с помощью scipy.optimize? - PullRequest
0 голосов
/ 30 августа 2018

Я выполняю подбор кривой, используя scipy.optimize. Я только хочу соответствовать первой части и последней части спектра. Средняя часть спектра имеет все интересные особенности, поэтому я явно не хочу вписываться в этот регион. Как ты мог это сделать?

Например:

import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import numpy as np 
from numpy.polynomial.polynomial import polyfit

%matplotlib inline
import matplotlib.pyplot as pl

def func(x, a, b, c):
    return a * np.exp(-b * x) + c

xdata = np.linspace(0, 4, 50)
y = func(xdata, 2.5, 1.3, 0.5)
np.random.seed(1729)
y_noise = 0.2 * np.random.normal(size=xdata.size)
ydata = y + y_noise
plt.plot(xdata, ydata, 'b-', label='data')

enter image description here

Интересующая особенность находится между 2 и 2,5, поэтому я не хочу делать кривую в этом диапазоне. Я просто хочу сделать кривую до 2 и после 2,5. Как я могу сделать это с помощью scipy.optimize? Потому что проблема, которую я получаю, заключается в том, что она выполняет подбор по всему спектру. Любая помощь будет оценена.

1 Ответ

0 голосов
/ 03 сентября 2018

Эта задача (при условии, что я правильно понял вопрос и, как отметил Джеймс Филлипс в своем комментарии) довольно проста. Однако есть несколько способов добиться этого. Вот один из них:

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

def decay( x, a, b, c ):
    return a + b * np.exp( - c * x )

xList = np.linspace( 0, 5, 121 )
yList = np.fromiter( ( .6 * np.exp( -( x - 2.25 )**2 / .05 ) + decay( x, .3, 1, .6) + .05 * np.random.normal() for x in xList ), np.float )

takeList = np.concatenate( np.argwhere( np.logical_or(xList < 2., xList > 2.5) ) )
featureList = np.concatenate( np.argwhere( np.logical_and(xList >= 2., xList <= 2.5) ) )

xSubList = xList[ takeList ]
ySubList = yList[ takeList ]
xFtList = xList[ featureList ]
yFtList = yList[ featureList ]

myFit, _ = curve_fit( decay,  xSubList, ySubList )

fitList = np.fromiter( ( decay( x, *myFit) for x in xList ), np.float )
cleanY = np.fromiter( ( y - decay( x, *myFit) for x,y in zip( xList, yList ) ), np.float )

fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )
ax.plot( xList, yList )
ax.plot( xSubList, ySubList - .1, '--' ) ## -0.1 offset for visibility
ax.plot( xFtList, yFtList + .1, ':' ) ## +0.1 offset for visibility
ax.plot( xList, fitList, '-.' )
ax.plot( xList, cleanY ) ## feature without background
plt.show()

Getting the feature without background

...