Open timbo112711 opened 1 year ago
Hello @timbo112711, thank you for your inquiry.
I created beta-hill
branch that you could try out.
Although experimental, it supports user-defined fitting function, e.g.,
y = beta - ((beta * EC50**nH) / (x**nH + EC50**nH))
How to use:
x_data = [0.01, 1.01, 1.38, 1.63, 1.88, 2.13, 2.38, 2.63, 2.88, 3.13, 3.38,
3.63, 3.88, 4.13, 4.38, 4.63, 4.88, 5.13, 5.38, 5.63, 5.88, 6.13,
6.38, 6.63, 8.38]
y_data = [0. , 0. , 0. , 0.03334, 0.04444, 0.11364, 0.19048,
0.3063 , 0.32 , 0.62366, 0.78 , 0.94444, 0.9495 , 1.26416,
1.54286, 1.50428, 1.61224, 1.85568, 1.88334, 1.86274, 1.91804,
1.92792, 1.95744, 1.96492, 2.]
from hillfit.experimental import UserDefined
def beta_hill(x, beta, EC50, nH):
'''User-defined fitting func.'''
y = beta - ((beta * EC50**nH) / (x**nH + EC50**nH))
return y
myfunc = UserDefined(x_data, y_data, beta_hill)
myfunc.fitting(curve_fit_kws={"maxfev": 1000})
I would be grateful if you could give me comments on this new feature.
Best, Hiroaki
Hi @himoto, thank you so much for the quick reply on this. My team and I will try out the new beta-hill
branch. Feedback to come!
Cheers, Tim
Hello @himoto,
Thanks again for this quick experimental feature!
We were giving it a test run and had a question on how we would go about inputting the beta
arg for the UserDefined
equation. Here is an example:
we would run an OLS regression that looks something like this:
sales = int + βTV + βRadio + βYouTube
where β
is the regression coefficient.
Looking only at TV here, say β
was 0.980
. We want to take the 0.980
and inject that into the Hill equation. Something like this:
y = 0.980 - ((0.980 * EC50**nH) / (x**nH + EC50**nH))
.
This could be a result of my not so great programming skills, but would we add that 0.980
into curve_fit_kws
arg while fitting?
Hi @timbo112711,
If I understand what you would like to do correctly, you can do it in following two ways:
def beta_hill(x, EC50, nH):
'''User-defined fitting func.'''
y = 0.980 - ((0.980 * EC50**nH) / (x**nH + EC50**nH))
return y
Then run the rest of code I showed.
curve_fit_kws
:You can specify lower and upper bounds on parameters via curve_fit_kws["bounds"]
.
In your case, since you do not have to search beta
, you can set search bounds in the following way:
import sys
myfunc.fitting(
curve_fit_kws={
"bounds": ((0.980 - sys.float_info.epsilon, -np.inf, -np.inf), (0.980, np.inf, np.inf)
}
)
# beta is fixed to 0.980, EC50 and nH are searched in (-inf, inf).
The reason I subtract sys.float_info.epsilon
, infinitesimal value, is that without doing this, you will get a ValueError:
ValueError: Each lower bound must be strictly less than each upper bound.
Hi @himoto,
Got it that make sense. Thanks for the guidance. Stay tuned!
If one wanted to modify the current Hill equation from
y = bottom + ((top - bottom) * x**nH) / (EC50**nH+ x**nH)
to
y = beta - ((beta * EC50**nH) / (x**nH + EC50**nH))
where
beta
is a regression coefficient from an OLS Media Mix Model.would there be an easy solution for this or would the whole
HillFit
class need to be modified?Reference: Section 2.2, equation 5 Bayesian Methods for Media Mix Modeling with Carryover and Shape Effects