Кривая подгонка нескольких выходов из одной функции с Scipy - PullRequest
0 голосов
/ 06 февраля 2019

ОК, у меня есть функция, которая использует диапазон параметров, чтобы вычислить влияние на две отдельные переменные во времени.Эти переменные уже были сопоставлены с некоторыми существующими данными для минимизации отклонения (показано ниже) example

Я хочу иметь возможность проверить предыдущую работу и сопоставить новые данные,Я пытался использовать функцию scipy.optimize.curve_fit, складывая данные x и y, полученные из моей функции (как предложено здесь: подгоняет несколько параметрических кривых с помощью scipy ).

Возможно, это неправильный метод, или я просто неправильно понимаю, но мой код продолжает сталкиваться с ошибкой типа TypeError: Improper input: N=3 must not exceed M=2

Мой упрощенный код прототипа был первоначально взят отсюда: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html

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

def func(x, a, b, c):
    result = ([],[])
    for i in x:
        #set up 2 example curves
        result[0].append(a * np.exp(-b * i) + c)
        result[1].append(a * np.exp(-b * i) + c**2)
    return result #as a tuple containing 2 lists

#Define the data to be fit with some noise:
xdata = list(np.arange(0, 10, 1))
y = func(xdata, 2.5, 5, 0.5)[0]
y2 = func(xdata, 1, 1, 2)[1]

#Add some noise
y_noise = 0.1 * np.random.normal(size=len(xdata))
y2_noise = 0.1 * np.random.normal(size=len(xdata))

ydata=[]
ydata2=[]

for i in range(len(y)): #clunky
    ydata.append(y[i] + y_noise[i])
    ydata2.append(y2[i] + y2_noise[i])

plt.scatter(xdata, ydata, label='data')
plt.scatter(xdata, ydata2, label='data2')
#plt.plot(xdata, y, 'k-', label='data (original function)')
#plt.plot(xdata, y2, 'k-', label='data2 (original function)')

#stack the data
xdat = xdata+xdata
ydat = ydata+ydata2

popt, pcov = curve_fit(func, xdat, ydat)

plt.plot(xdata, func(xdata, *popt), 'r-',
         label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))

plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

Любая помощь высоко ценится!

1 Ответ

0 голосов
/ 06 февраля 2019

Вот пример графического кода, который объединяет два разных уравнения с одним общим параметром, если это выглядит так, как вам нужно, его можно легко адаптировать для вашей конкретной задачи.

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

y1 = np.array([ 16.00,  18.42,  20.84,  23.26])
y2 = np.array([-20.00, -25.50, -31.00, -36.50, -42.00])
comboY = np.append(y1, y2)

x1 = np.array([5.0, 6.1, 7.2, 8.3])
x2 = np.array([15.0, 16.1, 17.2, 18.3, 19.4])
comboX = np.append(x1, x2)

if len(y1) != len(x1):
    raise(Exception('Unequal x1 and y1 data length'))
if len(y2) != len(x2):
    raise(Exception('Unequal x2 and y2 data length'))


def function1(data, a, b, c): # not all parameters are used here, c is shared
        return a * data + c

def function2(data, a, b, c): # not all parameters are used here, c is shared
        return b * data + c


def combinedFunction(comboData, a, b, c):
    # single data reference passed in, extract separate data
    extract1 = comboData[:len(x1)] # first data
    extract2 = comboData[len(x1):] # second data

    result1 = function1(extract1, a, b, c)
    result2 = function2(extract2, a, b, c)

    return np.append(result1, result2)


# some initial parameter values
initialParameters = np.array([1.0, 1.0, 1.0])

# curve fit the combined data to the combined function
fittedParameters, pcov = curve_fit(combinedFunction, comboX, comboY, initialParameters)

# values for display of fitted function
a, b, c = fittedParameters

y_fit_1 = function1(x1, a, b, c) # first data set, first equation
y_fit_2 = function2(x2, a, b, c) # second data set, second equation

plt.plot(comboX, comboY, 'D') # plot the raw data
plt.plot(x1, y_fit_1) # plot the equation using the fitted parameters
plt.plot(x2, y_fit_2) # plot the equation using the fitted parameters
plt.show()

print('a, b, c:', fittedParameters)
...