Week 5 - Curve fitting
Aim: To write code in Python to perform curve fitting for the given data and to determine the best fit.
Objectives:
- To fit a linear and cubic polynomial for a given data and to get the best fit out of the two fits
- To get a perfect curve fit
Theory:
- Curve fitting is the way we model or represent a data spread by assigning the best fit function (curve) along with the entire range. Ideally, it will capture the trend in the data and allow us to make predictions of how the data series will behave in the future.
- It is a statistical technique used to drive coefficient values for equations that express the value for one (dependent) variable as a function of another (independent variable). It has its engineering application in trend analysis, and hypothesis testing (which is used to compare the existing mathematical model with measured data.
- It is the process of formulating a mathematical function that has the best fit for the series of given data points. Best fit means to construct a curve where the distances between the actual and the predicted values are minimum.
- A perfect fit means that the error between the actual and predicted values is zero.
Code:
# A program to measure fitness characteristics for the linear and cubic polynomial for the Cp data:
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_l = function_0(np.array(temperature), *popt)
plt.figure(1)
plt.plot(temperature,cp,'k--')
plt.plot(temperature,fit_cp_l,color='red',linewidth = 1)
plt.legend(['Actual data','Curve fit'])
plt.xlabel('Temperature (K)')
plt.ylabel('Cp')
plt.title('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')
plt.title('Cubic Curve fitting')
plt.show()
'''
Measuring 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/l)^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_l[i]))))
linear_sse = linear_sse+pow(linear_error,2)
linear_ssr = linear_ssr+ np.sum(pow((fit_cp_l[i] - m),2))
print('For Linear Curve Fit')
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/l),0.5)
print('linear_RMSE :',linear_rmse)
print('')
# For Cubic curve fit
cubic_sse = 0
cubic_ssr = 0
for j in range(l):
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))
print('For Cubic Curve Fit')
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/l),0.5)
print('cubic_RMSE :',cubic_rmse)
Code Explanation:
- At first, necessary modules such as math,matplotlib,NumPy,scipy are imported to perform their respective functions.
- Two functions are defined which return linear and cubic equations.
- The following data is loaded into Python by placing it in the 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.
- From the data obtained, two individual column matrices of temperature and specific heat are derived.
- 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.
- 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.
- To measure the fitness characteristics for both the curves, various parameters such as SSESSE,SSRSSR,SSTSST,R2R2,RMSERMSE are calculated. The plot which has highest R2R2 or closest to 1 is considered to be a good fit.
Results:


Output:

Question & Answer:
1. What does popt and pcov mean?
Ans: 'popt' represents the matrix that stores and extracts the coefficients for the fitting functions according to the general equations defined.
pcov' represents the square matrix that stores the estimated values of covariance of the coefficients of the above. The diagonal elements of this square matrix also represent the variance of these coefficients.
2. What does np.array(temperature) do?
Ans. This command converts each value of temperature in the data file into an array using the NumPy module.
3. What does the * in *popt mean?
Ans. *in *popt' indicates and returns each coefficient stored in popt array.
4. What needs to be done in order to make the curve fit perfect?
Ans. To make the curve fit perfect, the dataset can be split into multiple parts and the curve fitting must be done to the individual parts. Another method is to use a higher order polynomial to get the correct fit
CONCLUSION:
- We can conclude that to make the curve fit good R2 should be close to 1.
- It can be found from the results obtained as for linear curve fit R2 is approximately 0.92 and for the 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 R2 will inch towards 1 and fit will be assumed to be good.