Как выполнить подгонку нелинейной кривой и найти параметр подгонки, используя Python с пользовательской функцией? - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть следующий набор данных:

x = 0, 5, 10, 15, 20, 25, 30

y = 0, 0.13157895, 0.31578947, 0.40789474, 0.46052632, 0.5, 0.53947368

Теперь я хочу построить эти данные и сопоставить этот набор данных с моей определенной функцией f(x) = (A*K*x/(1+K*x)) и найти параметры A и K?

Я написал следующий python сценарий, но кажется, что он не может выполнить то, что мне нужно:

import matplotlib.pyplot as plt

import numpy as np

from scipy.optimize import curve_fit

x = np.array([0, 5, 10, 15, 20, 25, 30])

y = np.array([0, 0.13157895, 0.31578947, 0.40789474, 0.46052632, 0.5, 0.53947368])

def func(x, A, K):

    return (A*K*x / (1+K*x))

plt.plot(x, y, 'b-', label='data')


popt, pcov = curve_fit(func, x, y)

plt.plot(x, func(x, *popt), 'r-', label='fit')

plt.xlabel('x')

plt.ylabel('y')

plt.legend()

plt.show()

Тем не менее, он не дает наилучшего соответствия кривой. Может ли кто-нибудь помочь мне с изменениями в сценарии python или в новом сценарии, где я могу правильно сопоставить данные с желаемой функцией подбора?

Ответы [ 2 ]

3 голосов
/ 30 апреля 2020

Класси c проблема: Вы не дали ни одного начального предположения для A и K. В этом случае значение по умолчанию будет 1 для всех параметров, что не подходит для вашего набора данных, и примерка будет сходиться куда-то еще. Вы можете выяснить предположения по-разному: просматривая данные по реальному значению параметров и т. Д. c .. Вы можете угадать значения с параметром p0, равным scipy.optimize.curve_fit. Он принимает список значений в том порядке, в котором они находятся в func, который вы хотите оптимизировать. Я использовал 0.1 для обоих, и я получил эту кривую:

popt, pcov = curve_fit(func, x, y, p0=[0.1, 0.1])

1

0 голосов
/ 30 апреля 2020

Попробуйте Minuit , который является пакетом, реализованным в Cern.

from iminuit import Minuit
import numpy as np
import matplotlib.pyplot as plt

def func(x, A, K):
    return (A*K*x / (1+K*x))

def least_squares(a, b):
    yvar = 0.01
    return sum((y - func(x, a, b)) ** 2 / yvar)

x = np.array([0, 5, 10, 15, 20, 25, 30])
y = np.array([0, 0.13157895, 0.31578947, 0.40789474, 0.46052632, 0.5, 0.53947368])

m = Minuit(least_squares, a=5, b=5)
m.migrad() # finds minimum of least_squares function
m.hesse()  # computes errors 
plt.plot(x, y, "o")
plt.plot(x, func(x, *m.values.values()))

# print parameter values and uncertainty estimates
for p in m.parameters:
    print("{} = {} +/- {}".format(p, m.values[p], m.errors[p]))

И результат:

a = 0,955697134431429 +/- 0,4957121286951612

b = 0,045175437602766676 +/- 0,04465599806912648

enter image description here

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