## [Python] Python curve fitting

Yngz_ Miao 2020-11-13 07:51:29
python python curve fitting

python As a simple and convenient language for scientific calculation , Curve fitting is one of the necessary functions . In this paper, how to do curve fitting is explained .

The data to be fitted in this paper is ：

``````x = np.arange(1, 31, 1)
y = np.array([20, 23, 26, 29, 32, 35, 38, 45, 53, 62, 73, 86, 101, 118, 138, 161, 188, 220, 257, 300, 350, 409, 478, 558, 651, 760, 887, 1035, 1208, 1410])
``````

## Polynomial fitting

By Taylor's formula ： Any function can be divided into polynomial expressions similar to this function .

The function needed for polynomial fitting is `np.polyfit`, Its usage is ：

``````def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
"""
Least squares polynomial fit.
Fit a polynomial ``p(x) = p[0] * x**deg + ... + p[deg]`` of degree `deg`
to points `(x, y)`. Returns a vector of coefficients `p` that minimises
the squared error.
``````

The parameters that need to be concerned are 3 individual ：x、y They are coordinate sequences of scattered points to be fitted ,deg Is the highest number of terms of the polynomial to be fitted .

for example ：

``````# coding=utf-8
import pylab
import numpy as np
if __name__ == "__main__":
x = np.arange(1, 31, 1)
y = np.array([20, 23, 26, 29, 32, 35, 38, 45, 53, 62, 73, 86, 101, 118, 138, 161, 188, 220, 257, 300, 350, 409, 478, 558, 651, 760, 887, 1035, 1208, 1410])
z1 = np.polyfit(x, y, 3) # Curve fitting , The return value is the coefficients of the polynomial
p1 = np.poly1d(z1) # The return value is a polynomial expression , It's a function
print(p1)
y_pred = p1(x) # According to the polynomial expression of the function , solve y
# print(np.polyval(p1, 29)) Solve a specific problem according to a polynomial x Corresponding y value
# print(np.polyval(z1, 29)) Solve a specific problem according to a polynomial x Corresponding y value
plot1 = pylab.plot(x, y, '*', label='original values')
plot2 = pylab.plot(x, y_pred, 'r', label='fit values')
pylab.title('')
pylab.xlabel('')
pylab.ylabel('')
pylab.legend(loc=3, borderaxespad=0., bbox_to_anchor=(0, 0))
pylab.show()
pylab.savefig('p1.png', dpi=200, bbox_inches='tight')
``````

The result of running the script is ：

``````[email protected]:~/test/blog\$ python nihe.py
3 2
0.1215 x - 3.045 x + 28.62 x - 34.47
``````

Fit the result of drawing ：

## Non polynomial fitting

Although polynomial fitting can be done arbitrarily , But in some cases , We want to synthesize the form of complex functions , Like logarithm 、 Index, etc . In this case, polynomial fitting can not be used . It should be noted that , If a logarithmic or exponential fit is needed , There is no easy way to do it once and for all , Need to guess ！

in other words , If polynomial fitting is needed , You have to know the approximate curve form of the scatter in general , Approximate function form .

such as , The scatter in the example looks like a function of the exponential distribution , So we can give func Function of ：

``````def func(x, a, b, c):
return b * np.power(a, x) + c
``````

Just give the concrete function form ( It can be arbitrary , As long as you can write it out ), use ` least square ` The way to approach and fit , That is to find out the coefficients of the function . What is used at this time is `scipy.optimize` Under bag `curve_fit` Function ：

``````# coding=utf-8
import pylab
import numpy as np
import sys, os
from scipy.optimize import curve_fit
def func(x, a, b, c):
return b * np.power(a, x) + c
if __name__ == "__main__":
x = np.arange(1, 31, 1)
y = np.array([20, 23, 26, 29, 32, 35, 38, 45, 53, 62, 73, 86, 101, 118, 138, 161, 188, 220, 257, 300, 350, 409, 478, 558, 651, 760, 887, 1035, 1208, 1410])
popt, pcov = curve_fit(func, x, y) # Curve fitting ,popt Is the parameter of the function list
y_pred = [func(i, popt[0], popt[1], popt[2]) for i in x] # Use functions and function parameters directly list To carry out y The calculation of the value
print(popt)
plot1 = pylab.plot(x, y, '*', label='original values')
plot2 = pylab.plot(x, y_pred, 'r', label='fit values')
pylab.title('')
pylab.xlabel('')
pylab.ylabel('')
pylab.legend(loc=3, borderaxespad=0., bbox_to_anchor=(0, 0))
pylab.show()
pylab.savefig('p1.png', dpi=200, bbox_inches='tight')
``````

The result of running the script is ：

``````[email protected]:~/test/blog\$ python nihe.py
[ 1.16791847 13.39168895 1.24633734]
``````

Fit the result of drawing ：