Exceptional weird results using a curve

When I try to fit my data, the results are a bit strange and I don’t understand why? The resulting fitting is flat, and the first input e = 0. It seems that somewhere it increased the division error. The only working case is when I change e [0] = 1.0e-9

The result is the following: enter image description here

From the example here it seems that my example is not so far from what I read, but I remain stuck, so could you help me please, what will be wrong in my case?

import numpy as np from scipy.optimize import curve_fit import matplotlib.pyplot as plt src_s = np.array((45.59,50.66664,59.74871,65.71018,72.76012,79.06256,84.13755,90.39944, 96.33653,101.65667,106.27968,110.76301,114.41808,117.21922,120.51836)) src_e = np.array((0.0,0.00126,0.00503,0.00804,0.01228,0.01685,0.02127,0.02846,0.03666, 0.04581,0.05620,0.06882,0.08005,0.09031,0.10327)) # plot source data plt.plot(src_e, src_s, 'o') # fitting function def sigma(e, k ,n): return k*(e**n) # find parameters curve fitting param, var = curve_fit(sigma, src_e, src_s) new_e = np.linspace(src_e.min(), src_e.max(), 50) plt.plot(new_e, sigma(new_e, *param)) # modify first input src_e[0]=1.0e-9 # relaunch parameters curve fitting param, var = curve_fit(sigma, src_e, src_s) new_e = np.linspace(src_e.min(), src_e.max(), 50) plt.plot(new_e, sigma(new_e, *param)) plt.show() 

Thanks in advance for your help.

+6
source share
2 answers

The root of the problem is a poor initial assumption about the parameters (at the initial stage, there is no initial parameter for curve_fit ).

The objective function can be easily linearized. Let's do it, then do a linear regression to get a good set of initial guessing parameters for curve_fit (go to it with p0= ). The correspondence obtained is better (with fewer residues) and there is no need to replace the first value 1e-9 :

 In [38]: src_e[0]=1.0e-9 # relaunch parameters curve fitting param, var = curve_fit(sigma, src_e, src_s) new_e = np.linspace(src_e.min(), src_e.max(), 50) src_e[0]=0 plt.plot(new_e, sigma(new_e, *param)) plt.plot(src_e, src_s, 'ro') plt.savefig('1.png') print 'Residue is:', ((sigma(src_e, *param)-src_s)**2).sum() Residue is: 2168.65307587 

enter image description here

 In [39]: import scipy.stats as ss src_e[0]=0 V=ss.linregress(np.log(src_e)[1:], np.log(src_s)[1:]) #avoid log(0) param, var = curve_fit(sigma, src_e, src_s, p0=(np.exp(V[1]), V[0])) new_e = np.linspace(src_e.min(), src_e.max(), 50) plt.plot(new_e, sigma(new_e, *param)) plt.plot(src_e, src_s, 'ro') plt.savefig('1.png') print 'Residue is:', ((sigma(src_e, *param)-src_s)**2).sum() Residue is: 2128.85364181 

enter image description here

+2
source

The first point cannot be on the curve, so you need to change the formula of the curve:

 import numpy as np from scipy.optimize import curve_fit import matplotlib.pyplot as plt src_s = np.array((45.59,50.66664,59.74871,65.71018,72.76012,79.06256,84.13755,90.39944, 96.33653,101.65667,106.27968,110.76301,114.41808,117.21922,120.51836)) src_e = np.array((0.0,0.00126,0.00503,0.00804,0.01228,0.01685,0.02127,0.02846,0.03666, 0.04581,0.05620,0.06882,0.08005,0.09031,0.10327)) # plot source data plt.plot(src_e, src_s, 'o') def sigma(e, k ,n, offset): return k*((e+offset)**n) # find parameters curve fitting param, var = curve_fit(sigma, src_e, src_s) new_e = np.linspace(src_e.min(), src_e.max(), 50) plt.plot(new_e, sigma(new_e, *param)) 

here is the result:

enter image description here

0
source

Source: https://habr.com/ru/post/969388/


All Articles