Week 5 - Curve fitting
Aim:To fit a linear and cubic polynomial curve for the given specific heat data.
Theory:Curve fitting is the process of constructing a curve, or mathematical functions, which possess the closest proximity to the real series of data. By curve fitting, we can mathematically construct the functional relationship between the observed dataset and parameter values, etc. It is highly effective in the mathematical modeling of some natural processes.
Governing Equations:
The following equations are basically used to calculate the error between the fitted curve and the data points.
Lesser the error, more efficient is the fit.
If y=f(x)R2`is the fit curve then
SSRR2 is defined as follows,
SSR=`n∑i=1(f(x(i))-Mean)2`R2
Similarly SSER2 is defined as follows,
SSE=`n∑i=1(Y(i)-f(x(i)))2`
Now the term SST is given by the summation of SSR and SSE
SST=SSR+SSE
From here, we can calculate the value of `R^2`,
`R^2`=`(SSR)/(SST)`
where ,
- SSR- sum of squares of the regression
- SSE- The sum of squares due to error
- SST- The sum of SSR and SSE
- R2R2- The ratio of SSR and SST
The value of the R2R2` tells us about the gooodness of fit.
If R2R2=1, the fit is considered to be best fit for the given data set
If R2R2=0, the fit is considered to be worst fit for the given data set
Main code:
import math #importing libraries
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
def func1(t,a,b): #first order linear equation
return a*t+b
def func2(t,a,b,c,d): #third order equation
return a*pow(t,3)+b*pow(t,2)+c*pow(t,1)+d
def func3(t,a,b,c,d,e): #fourth order equation
return a*pow(t,4)+b*pow(t,3)+c*pow(t,2)+d*t+e
def func4(t,a,b,c,d,e,f,g):
return a*pow(t,6)+b*pow(t,5)+c*pow(t,4)+d*pow(t,3)+e*pow(t,2)+f*t+g #sixth order
def func5(t,a,b,c,d,e,f,g,h,i): #eigth order
return a*pow(t,8)+b*pow(t,7)+c*pow(t,6)+d*pow(t,5)+e*pow(t,4)+f*pow(t,3)+g*pow(t,2)+h*t+i
def reading(): #reading the data file and assigning the variables to those data
temparature=[]
cp=[]
for line in open('data','r'):
values=line.split(',')
temparature.append(float (values[0]))
cp.append(float (values[1]))
return [temparature,cp]
#finding the goodness of the fit
def gof(fit_cp,popt): #A functon to determine the goodness of fit
#finding R square
ssr=np.sum(pow((np.array(np.array(fit_cp)-np.mean(cp))),2))
sse=np.sum(pow(np.array(np.array(cp)-np.array(fit_cp)),2))
sst=ssr+sse
R_square=ssr/sst
#Adjusted R_square
n=len(cp)
k=0
arsq=1-((1-R_square)*(n-1)/(n-k-1))
#Root mean squared error(RMSE)
rmse=np.sqrt(sse/n)
print("{:2d} {:21.6f} {:12.4f} {:12.5f} {:19.4f}".format(len(popt)-1,sse,R_square,arsq,rmse)) #printing the values in the required spacings
#main program
temparature,cp=reading()
#getting the coefficinets and covariance of the coefficients
popt1,pcov1=curve_fit(func1,temparature,cp)
popt2,pcov2=curve_fit(func2,temparature,cp)
popt3,pcov3=curve_fit(func3,temparature,cp)
popt4,pcov4=curve_fit(func4,temparature,cp)
popt5,pcov5=curve_fit(func5,temparature,cp)
#fitting the curve
fit_cp1=func1(np.array(temparature),*popt1)
fit_cp2=func2(np.array(temparature),*popt2)
fit_cp3=func3(np.array(temparature),*popt3)
fit_cp4=func4(np.array(temparature),*popt4)
fit_cp5=func5(np.array(temparature),*popt5)
#plotting the results
plt.figure()
plt.plot(temparature,cp,color='r',lw=2) #originaal curve
plt.plot(temparature,fit_cp1,color='g',lw=2) # fitting second order curve
plt.plot(temparature,fit_cp2,color='b',lw=2) #fitting fourth order curve
plt.xlabel('Temperature')
plt.ylabel('Specific heat')
plt.title('fitting the curves of different order to the original data set')
plt.legend(['Actual data','linear fit','cubic fit'])
plt.show()
#perfect fit
plt.figure()
plt.plot(temparature,cp,color='r',lw=2) #originaal curve
plt.plot(temparature,fit_cp5,color='b',lw=2)
plt.xlabel('Temperature')
plt.ylabel('Specific heat')
plt.legend(['Actual data','perfect fit'])
plt.title('Perfect fit')
plt.show()
#Tabulation of the results
print(' Goodness of fit')
print('----------------------------------------------------------------------------------')
print('Order Sum of squared error Rsquare Adjusted Rsquare Root mean square error')
print('-----------------------------------------------------------------------------------')
gof(fit_cp1,popt1) #calling the functions to calculate the goodness of fit
gof(fit_cp2,popt2)
gof(fit_cp3,popt3)
gof(fit_cp4,popt4)
gof(fit_cp5,popt5)
Code Explanation:
- The required libraries are imported
- Now the functions which indicates the polynomial are defined with the names func1,func2,func3,func4, and func5 which represents first,third,fourth,sixth and eigth order polynomials respectievely.
- Now the data file is read using a function named reading which reads the data and returns the data back to the function
- Again a function is defined which calculates the goodness of fit .Here, SSE,SSR and R square are calculated.
- Now the coefficients are determined using curve_fit command which takes the name of the function and the temperature and cp values as input arguments.
- It returns the popt and pcov which are coefficients and the covariance of those coefficients respectievely
- Now the curve is fit into the original data set.This is done by determining the new values of the cp and naming it to be fit_curve and the same values are fed into the polynomial functions
- Now the plots are made beteen the original data, quadratic fit, and the cubic fit .
- Legends,title, x and y labels are provided
- The perfect fit can be obtained when we try fitting a polynomial having eigth order.
- Thus , this can be considered as perect fit and is shown as a separate figure.
- Finally, the goodness of fit function is called and the results obtained from the calculations are tabulated.
Results and plot:
The above figure shows the values of R-square , Adjusted R-square and The RMSE
This plot shows how different polynomials are fit into the original data set .
A perfect fit obatined when a eigth order polynomial is fit into the original data set.
Questions Asked:
1. What does popt and pcov mean?
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. The diagonals provide the variance of the parameter estimate.
2. What does np.array(temperature) do?
This is a an array which conatains the values of the temperature from the provided data set.The term np suggests the usage of the numpy module which helps us to make array operations.
3. What does the * in *popt mean?
The star(*) mark is a pointer which gives the address of the coefficients of the particular polynomial
4. Write code to fit a linear and cubic polynomial for the Cp data. Explain if your results are good or bad?
The fit has already made and are shown above.The fit is not a good fit.Since there are a lot of errors between the actual data set and the fitte curve
5. What needs to be done in order to make the curve fit perfect?
The main objective is to minimise the error between the acual data set and the fitted curve. That is why the RMSE value should be as low as possible.Lower the RMSE values more perfect will be the fit.
Reference:
https://www.youtube.com/watch?v=eTpXGyzok14
Conclusion:
Curve fitting is a very good weapon which helps in determining the variation of the present data in the future.This helps in solving complex problems and predicts the future situations using present data.