Home > Blockchain >  Fitting Data w/ Curve Fit Then Find Out if Data is above / below curve fit
Fitting Data w/ Curve Fit Then Find Out if Data is above / below curve fit

Time:01-10

I generated an exponential curve fit for the proxy data below. After fitting the model to the data, I need to determine if another sample second sample, row by row, is above or below the fit line. Where I am struggling is how to determine if the second sample data is above or below the fit line.

#Sample Data for generating the exponential curve fit model
ys = np.array([40951088., 35375058., 22160211., 21306439., 20980581., 15379697.,
       10308974., 16793804.,  6867746.,  5952455.,  4505347.,  4768728.,
        5254116.,  2183644.,  3350415.,  1992107.,  1449918.,   985307.,
        2804293.,  2515258.,   884647.,   251409.,   901582.])

xs = np.array([ 0. ,  0.5,  1. ,  1.5,  2. ,  2.5,  3. ,  3.5,  4. ,  4.5,  5. ,
        5.5,  6. ,  6.5,  7. ,  7.5,  8. ,  8.5,  9. ,  9.5, 10. , 10.5,
       11.])

def monoExp(x, m, t, b):
    return m * np.exp(-t * x)   b

# perform the fit
p0 = (2000, .1, 50) #approximate values
params, cv = scipy.optimize.curve_fit(monoExp, xs, ys, p0, maxfev=5000)
m, t, b = params
sampleRate = 20_000 # Hz
tauSec = (1 / t) / sampleRate

# determine quality of the fit
squaredDiffs = np.square(ys - monoExp(xs, m, t, b))
squaredDiffsFromMean = np.square(ys - np.mean(ys))
rSquared = 1 - np.sum(squaredDiffs) / np.sum(squaredDiffsFromMean)
print(f"R² = {rSquared}")

# plot the results
plt.plot(xs, ys, '.', label="data")
plt.plot(xs, monoExp(xs, m, t, b), '--', label="fitted")
plt.title("Fitted Exponential Curve")

# inspect the parameters
print(f"Y = {m} * e^(-{t} * x)   {b}")
print(f"Tau = {tauSec * 1e6} µs")

Here are the results from the code snippet above.

enter image description here

Now I want to determine whether or not the data from the second sample fits above or below the curve used for the first sample. Both ys and the second sample use xs as a sort of index (range from 0 to 11 with 0.5 steps).

second_ys = np.array([17623610, 32724312,   918384,   749818,   910372])
second_xs = np.array([0, 0, 0.5, 0, 11.5])

I cannot enter second_ys[0:1] into the forumla, because the answer is the error term:

x1 = 17623610 #second_ys[0:1]
39960941.909692936 * np.exp(-0.4000309715410416 * x1)   421846.9906738758
>>> 421846.9906738758

I am not sure how to determine if values along second_ys fall above or below the line.

When I plug the params back into the equation to see if the values are above or below the visually represented curve, it returns all of the same values:

monoExp(ys, params[0], params[1], params[2])
>>> array([421846.99067388, 421846.99067388, 421846.99067388, 421846.99067388,
       421846.99067388, 421846.99067388, 421846.99067388, 421846.99067388,
       421846.99067388, 421846.99067388, 421846.99067388, 421846.99067388,
       421846.99067388, 421846.99067388, 421846.99067388, 421846.99067388,
       421846.99067388, 421846.99067388, 421846.99067388, 421846.99067388,
       421846.99067388, 421846.99067388, 421846.99067388])

CodePudding user response:

since you have the fitted curve you can replace use the xs to determine the origin of the error vector ending in ys

The curve is monoExp(xs, m, t, b) accordingly to your plotting code, so you can get the error as follows.

err = ys - monoExp(xs, m, t, b)
plt.stem(xs, err)

enter image description here

  •  Tags:  
  • Related