[PYTHON] SciPy의 지수 곡선 피팅
PYTHONSciPy의 지수 곡선 피팅
두 개의 NumPy 배열 x와 y가 있습니다. 이 간단한 코드로 지수 함수와 curve_fit (SciPy)을 사용하여 데이터를 저장하려고 할 때
#!/usr/bin/env python
from pylab import *
from scipy.optimize import curve_fit
x = np.array([399.75, 989.25, 1578.75, 2168.25, 2757.75, 3347.25, 3936.75, 4526.25, 5115.75, 5705.25])
y = np.array([109,62,39,13,10,4,2,0,1,2])
def func(x, a, b, c, d):
return a*np.exp(b-c*x)+d
popt, pcov = curve_fit(func, x, y)
나는 잘못된 계수를 얻는다.
[a,b,c,d] = [1., 1., 1., 24.19999988]
문제가 무엇입니까?
해결법
-
==============================
1.첫 번째 주석 : a * exp (b - c * x) = (a * exp (b)) * exp (-c * x) = A * exp (-c * x)이므로 a 또는 b는 중복됩니다. 나는 b를 떨어 뜨리고 사용한다 :
첫 번째 주석 : a * exp (b - c * x) = (a * exp (b)) * exp (-c * x) = A * exp (-c * x)이므로 a 또는 b는 중복됩니다. 나는 b를 떨어 뜨리고 사용한다 :
def func(x, a, c, d): return a*np.exp(-c*x)+d
그것은 주요 문제가 아닙니다. 문제는 단순히 초기 초기 추측 (1을 모두 사용)을 사용하면 curve_fit이이 문제에 대한 해결책으로 수렴하지 못하는 것입니다. pcov를 확인하십시오. 당신은 그것이 inf임을 알 수 있습니다. c가 1이면 exp (-c * x) 값의 대부분이 0으로 언더 플로우하기 때문에 이는 놀랄 일이 아닙니다.
In [32]: np.exp(-x) Out[32]: array([ 2.45912644e-174, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000])
이것은 c가 작아야 함을 의미합니다. 더 나은 초기 추측은 말하자면 p0 = (1,1e-6, 1)입니다. 그 때 나는 얻는다 :
In [36]: popt, pcov = curve_fit(func, x, y, p0=(1, 1e-6, 1)) In [37]: popt Out[37]: array([ 1.63561656e+02, 9.71142196e-04, -1.16854450e+00])
이것은 합리적으로 보입니다.
In [42]: xx = np.linspace(300, 6000, 1000) In [43]: yy = func(xx, *popt) In [44]: plot(x, y, 'ko') Out[44]: [<matplotlib.lines.Line2D at 0x41c5ad0>] In [45]: plot(xx, yy) Out[45]: [<matplotlib.lines.Line2D at 0x41c5c10>]
-
==============================
2.먼저 방정식을 * np.exp (-c * (x-b)) + d로 수정하는 것이 좋습니다. 그렇지 않으면 지수가 항상 x = 0에 집중되어 항상 그렇지 않을 수도 있습니다. 또한 적당한 초기 조건을 지정해야합니다 (curve_fit의 네 번째 인수는 [a, b, c, d]의 초기 조건을 지정합니다).
먼저 방정식을 * np.exp (-c * (x-b)) + d로 수정하는 것이 좋습니다. 그렇지 않으면 지수가 항상 x = 0에 집중되어 항상 그렇지 않을 수도 있습니다. 또한 적당한 초기 조건을 지정해야합니다 (curve_fit의 네 번째 인수는 [a, b, c, d]의 초기 조건을 지정합니다).
이 코드는 잘 맞습니다.
from pylab import * from scipy.optimize import curve_fit x = np.array([399.75, 989.25, 1578.75, 2168.25, 2757.75, 3347.25, 3936.75, 4526.25, 5115.75, 5705.25]) y = np.array([109,62,39,13,10,4,2,0,1,2]) def func(x, a, b, c, d): return a*np.exp(-c*(x-b))+d popt, pcov = curve_fit(func, x, y, [100,400,0.001,0]) print popt plot(x,y) x=linspace(400,6000,10000) plot(x,func(x,*popt)) show()
from https://stackoverflow.com/questions/21420792/exponential-curve-fitting-in-scipy by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 상관 행렬 찾기 (0) | 2018.11.09 |
---|---|
[PYTHON] Paramiko : NAT 라우터 주변의 포트 포워딩 (0) | 2018.11.09 |
[PYTHON] 동일한 키에 대해 여러 값을 유지하면서 파일을 구성하는 방법은 무엇입니까? (0) | 2018.11.09 |
[PYTHON] 파이썬 사전에 항목을 삭제 한 후 메모리를 되찾기 (0) | 2018.11.09 |
[PYTHON] 지수 형식 / 과학 표기법이 아닌 일반 형식으로 부동 소수점 숫자 인쇄 (0) | 2018.11.09 |