For reproducibility reasons, I am sharing the simple dataset I am working here .
To make it clear of what I am doing - from column 2, I am reading the current row and compare it with the value of the previous row. If it is greater, I keep comparing. If the current value is smaller than the previous row's value, I want to divide the current value (smaller) by the previous value (larger). Accordingly, below is my source code.
import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import beta
protocols = {}
types = {"data_v": "data_v.csv"}
for protname, fname in types.items():
col_time,col_window = np.loadtxt(fname,delimiter=',').T
trailing_window = col_window[:-1] # "past" values at a given index
leading_window = col_window[1:] # "current values at a given index
decreasing_inds = np.where(leading_window < trailing_window)[0]
quotient = leading_window[decreasing_inds]/trailing_window[decreasing_inds]
quotient_times = col_time[decreasing_inds]
protocols[protname] = {
"col_time": col_time,
"col_window": col_window,
"quotient_times": quotient_times,
"quotient": quotient,
}
plt.figure(); plt.clf()
plt.plot(quotient_times, quotient, ".", label=protname, color="blue")
plt.ylim(0, 1.0001)
plt.title(protname)
plt.xlabel("quotient_times")
plt.ylabel("quotient")
plt.legend()
plt.show()
sns.distplot(quotient, hist=False, label=protname)
This gives the following plots.
As we can see from the plots
quotient_times
is less than 3 and the quotient remains 0.5 if the quotient_times
is greater than 3. I have also fitted it into a beta distribution using the following code
xt = plt.xticks()[0]
xmin, xmax = min(xt), max(xt)
lnspc = np.linspace(xmin, xmax, len(quotient))
alpha,beta,loc,scale = stats.beta.fit(quotient)
pdf_beta = stats.beta.pdf(lnspc, alpha, beta,loc, scale)
plt.plot(lnspc, pdf_beta, label="Data-V", color="darkblue", alpha=0.9)
plt.xlabel('$quotient$')
#plt.ylabel(r'$p(x|\alpha,\beta)$')
plt.title('Beta Distribution')
plt.legend(loc="best", frameon=False)
How can we fit the quotient
(defined above) into a sigmoid function to have a plot something like the following?
You want to fit a sigmoid
, or actually a logistic function . This can be varied in several ways, such as slope, midpoint, magnitude and offset.
Here's the code that defines that sigmoid
function and utilizes the scipy.optimize.curve_fit
function to minimize the error by tuning the parameters.
from scipy.optimize import curve_fit
def sigmoid (x, A, h, slope, C):
return 1 / (1 + np.exp ((x - h) / slope)) * A + C
# Fits the function sigmoid with the x and y data
# Note, we are using the cumulative sum of your beta distribution!
p, _ = curve_fit(sigmoid, lnspc, pdf_beta.cumsum())
# Plots the data
plt.plot(lnspc, pdf_beta.cumsum(), label='original')
plt.plot(lnspc, sigmoid(lnspc, *p), label='sigmoid fit')
plt.legend()
# Show parameters for the fit
print(p)
This gives you the following plot:
and the following parameter space (for the above used function):
[-1.82910694e+01 4.88870236e-01 6.15103201e-03 1.82895890e+01]
If you want to fit the variables quotient_time
and quotient
, you simply change the variables.
...
p, _ = curve_fit(sigmoid, quotient_times, quotient)
...
and plot it:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.