Curve fitting using python
Aim:
1. To write code to fit a linear and cubic polynomial for the Cp data.
2. To plot the linear and cubic fit curves along with the raw data points.
3. To measure the fitness characteristics for both the curves.
Theory- Curve Fitting- Curve fitting is the process of constructing a curve, or mathematical function, that has the best fit to a series of data points, possibly subject to constraints. Curve fitting can involve either interpolation, where an extract fit to the data is required, or smoothing, in which a 'smooth' function is constructed that approximately fits the data.
Polynomial cuve firring is a common tak for data analysis in many fields of science, engineering and social-science. The standard methods to fit a curve to data is to use the Least Square Method. In the method, the coefficients of the estimated polynomial are determined by minimizing the squares of errors between the data points and the fitted curve. This method is used to determine the relationship between an independent and dependent variable. The common term regession line is used foe a first-degree polynomial. Matlab has a simple function called Polyfit that alows an analyst to use the least square method. In this post, a simple example of polyfit is presented to determine the relationship between two variables in a noisy environment.
In order to obtain the curve, we use polyfit(x,y,r) and polyval(a,b) commands with r = 1,2 & 3
Linear Polynomial- Linear polynomial is any polynomial defined by an equation of the form p(x) = ax + b where a and b are real numbers and a is not equal to zero. A linear polynomial is the same as a degree 1 polynomial.
For example- 1) p(x) = 2x+3 2) g(x) = 4x + 1
Quadratic Polynomial - A polynomial with degree 2 is known as quadratic polynomial in one variable of the form ax^2 +bx +c, where a,b,c are real numbers and a is not equal to zero.
Cubic Polynomial- A polynomial whose degree is 3 is termed as cubic polynomial. Hence, any polynomial of th form ax^3 +bx^2 + cx +d, where a,b,c,d are real constants is called cubic polynomial if a is not equal to zero.
Examples of polynomial
Assume data (x1,y1), (x2,y2),.......(xn,yn) and assume the best fit for set of these points with y = f(x) under which the equation of the curve will be the best as possible as follows
How to choose it is best fit?
For finding a curve which satisfies the data points there are four steps which help us to measure the best fit-
- Sum of squares of errors (SSE)
- R-Square
- Adjusted R-Square
- Root mean square error (RMSE)
If R-Square value is between 0.9500 and 1.000 then it is considered as best fit.
R-Square- It is a quantity that measures how successful the fit is explaining the variation of the data, when it seems the higher the value of the R-Square is better fit and lower than it is bad fit. R-Square value ranges from 0 to 1. The value of R-Square can be calculated using the formula-
R2=SSRSST">R2=SSRSSTR2=SSRSST
If y = f(x) is the fit curve then SSR is defined as follows
SSR=n∑i=0(f(x(i))−mean2)">SSR=n∑i=0(f(x(i))−mean2)SSR=n∑i=0(f(x(i))−mean2)
similarly, SSE is definrd as
SST=n∑i=0(y(i)−f(x(i)))2">SST=n∑i=0(y(i)−f(x(i)))2SST=n∑i=0(y(i)−f(x(i)))2
From above we get.
SST = SSR + SSE
where, n is total number of data points available.
RMSE- This statistic is also known as the fit standard error and the standard error of the regression. It is an estimate of the standard deviation of the random component in the data and is defined as,
PYTHON CODE:
# A program for curve fitting
import math
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
# Curve fit function
# Linear function
def function_0(t,a,b):
return a*t + b
# Cubic function
def function_2(t,a,b,c,d):
return a*pow(t,3) + b*pow(t, 2) + c*t +d
# Reading thermodynamic data file
def read_file():
temperature = []
cp = []
for line in open ('data','r'):
values = line.split(',')
temperature.append(float(values[0]))
cp.append (float(values [1]))
return [temperature , cp]
# Main Program
temperature, cp = read_file()
popt, pcov = curve_fit(function_0, temperature, cp)
fit_cp_1 = function_0(np.array(temperature), *popt)
plt.figure(1)
plt.plot(temperature,cp, 'k--')
plt.plot(temperature, fit_cp_1, color='red',linewidth = 1)
plt.legend(['Actual data', 'Curve fit'])
plt.xlabel('Temperature (K)')
plt.ylabel('Cp (KJ/Kg*K)')
plt.title('Linear Curve fitting')
plt.grid()
plt.savefig('Linear Curve fitting')
plt.show()
popt, pcov = curve_fit(function_2, temperature,cp)
fit_cp_c = function_2(np.array (temperature), *popt)
plt.figure(3)
plt.plot(temperature,cp, 'k--')
plt.plot(temperature, fit_cp_c, color='red',linewidth = 1)
plt.legend( ['Actual data','Curve fit'])
plt.xlabel('Temperature (K)')
plt.ylabel('Cp (KJ/Kg*K)')
plt.title('Cubic Curve fitting')
plt.grid()
plt.savefig('Cubic Curve fitting')
plt.show()
"""
# Measuring parameters for the fitness characetristics of the curves
SSE (sum of error squared)
SSR (sum of squares of the regression)
SST = SSE + SSR
R^2 = SSR/SST
RMSE = (SSE/1)^0.5
Finding mean of Cp data
Mean = ( sum of all elements)/(total number of elements)"""
s = np.sum(cp)
l = np.size(cp)
m = s/l
print( 'Mean of all cp : ',m)
print('')
# For Linear curve fit
linear_SSE = 0
linear_SSR = 0
for i in range(l):
linear_error = abs ((np.sum( (cp[i] - fit_cp_1[i]))))
linear_SSE = linear_SSE + pow (linear_error,2)
linear_SSR = linear_SSR + np.sum(pow( (fit_cp_1[i] - m),2))
linear_SST = linear_SSE + linear_SSR
print('linear_SST :',linear_SST)
linear_R2 = linear_SSR/linear_SST
print('linear_R2 :',linear_R2)
linear_RMSE = pow( (linear_SSE/1),0.5)
print('linear_RMSE : ',linear_RMSE)
print('')
# For Cubic curve fit
cubic_SSE = 0
cubic_SSR = 0
for j in range(1):
cubic_error = abs(np.sum((cp[i] - fit_cp_c[i])))
cubic_SSE = cubic_SSE + (pow(cubic_error , 2))
cubic_SSR = cubic_SSR + np.sum(pow( (fit_cp_c[i] - m), 2))
cubic_SST = cubic_SSE + cubic_SSR
print('Cubic_SST :',cubic_SST)
cubic_R2= cubic_SSR/cubic_SST
print('Cubic_R2 :', cubic_R2)
cubic_RMSE = pow((cubic_SSE/1),0.5)
print('Cubic_RMSE :',cubic_RMSE)
EXPLANATION OF CODE :
1. At first necessary modules such as math,matplotlib,numpy,scipy are imported to perform their respective functions.
2. Two functions are defined which return linear and cubic equations.
3. The following data is loaded into Python by placing it in right directory and a function read_file is created. For loop is used to run each line by using 'open' command with 'r' to read it.
4. From the data obtained, two individual column matrices of temperature and specific heat are derived.
5. For curve fitting, 'popt' and 'pcov' are used as output for storing parameters obtained by 'curve_fit' command which takes input as the required function(linear or cubic) ,temperature and Cp. Now, another variable named 'fit_cp' stores the new values of Cp calculated by using temperature array.
6. Plots of both raw dataset and predicted dataset are made and compared to find fitness characteristics for both the curves for both linear and cubic polynomial.
7. To measure the fitness characteristics for both the curves, various parameters such as SSE, SSR, SST, RMSE are calculated. The plot which has highest R or closest to 1 is considered to be good fit.
RESULTS OF THE ABOVE MENTIONED PROGRAM
Errors occured:
The error says the list is not callable because I was trying to access/use a python list but using parenthesis for it. Parenthesis are used to call a function and because a list is not a function. To access/use a python list, you should use square brackets.
CONCLUSION: Hence we can conclude that to make curve fit good R should be close to 1. It can be found from the results obtained as for linear curve fit R2 is approximately 0.93 and for cubic curve fit it is nearly 0.99. So it can be said that cubic polynomial fits better than linear polynomial. If the order of the polynomial increases, the value of R will inch towards 1 and fit will be assumed to be good.
Question-answers
1. What doe popt and pcov mean?
Ans: popt- An array of optimal values for the parameters which minimizes the sum of squares of residuals. Pcov-2d array which contains the estimated covariance of popt.
2. What does np.array(temperature) do?
Ans: NumPy Arrays provides the ndim attribute that returns an integer that tells us how many dimensions the array has.
3. What does the *in *popt mean?
Ans: popt stores all the value for constraints in the function and the *(star) refers to address of all the constraints.
4. What needs to be done in order to make the curve fit perfect?
Ans: In order to make perfect fit, we must consider error estimates as well. Perfect fit means, the curve should fit the original curve without showing any errors (such as centering and scaling errors) in that particular degree of polynomial. Perfect fit can always be a best fit but best fit cannot be a perfect fit.To get the best fit of the curve we should go first for the geometric fitting and then after analyzing the data we should opt for the numerical values of the polynomial equations.
REFERENCES :
- https://projects.skill-lync.com/projects/Curve-Fitting-and-criterion-to-choose-best-fit-41860
- https://in.mathworks.com/help/curvefit/curve-fitting.html
- https://en.wikipedia.org/wiki/Curve_fitting
- https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html