4
$\begingroup$

I have ratios (or %changes) of x1 vs. x2 and y1 vs. y2, and so on. The initial x value matters, hence it is a non-linear function (negative exponential) in the form: y = c(1-e^(px))

That is, I need to estimate the value of "p" that minimizes residuals. "c" is already known.

For example,

When x1 (0.02) changes to x2 (0.03), I know the percentage change in y is 40%

When x3 (0.04) changes to x4 (0.08), I know the percentage change in y is 100%... and so on, I have a series of these percentage changes in y between two x values.

Any ideas other than brute force guessing the parameter value myself? Thank you so much I really need helps.

$\endgroup$
1
  • 1
    $\begingroup$ Is there any randomness here, or is the relationship between $y$ and $x$ deterministic? $\endgroup$ Commented Feb 11 at 20:16

1 Answer 1

2
$\begingroup$

Suppose the pair of $x$ values for a sample is $x_0$, $x_1$.

The percentage change in $y$ for the $x_0$, $x_1$ pair is defined as:

$$ \Delta y\% =\frac{y(x_1)-y(x_0)}{y(x_0)}\cdot100 $$

Substituting the formula $y=c\times(1-e^{px})$ and simplifying results in: $$ \Delta y\%=\frac{e^{px_0}-e^{px_1}}{1-e^{px_0}} $$

Since you have both $x_0$ and $x_1$ for each value of $\Delta y\%$, you can use an optimisation routine to fit the formula above to your data, resulting in an estimate of $p$.


Reproducible example in python:

I use scipy.optimize.curve_fit to fit a noisy set of observations. You could remove the noise term, or amplify it, depending on the nature of your data.

enter image description here

Imports and data: I synthesise a dataset comprising pairs of $(x_0, x_1)$, and their corresponding $\Delta y (\%)$.

import numpy as np from matplotlib import pyplot as plt # # Data for testing # np.random.seed(20) p_true = -0.5 def calc_y_change_percent(X, p): x0, x1 = X.T y_at_x0 = (1 - np.exp(p * x0)) y_at_x1 = (1 - np.exp(p * x1)) y_change_pct = (y_at_x1 - y_at_x0) / y_at_x0 * 100 return y_change_pct n_samples = 100 x0 = np.random.uniform(0.1, 0.5, size=n_samples) x1 = x0 + np.random.uniform(0, 1, size=n_samples) X = np.column_stack([x0, x1]) y_change_pct = calc_y_change_percent(X, p_true) + np.random.randn(n_samples) / 5 

Visualise data, estimate $p_{true}$, and report both $p_{true}$ and $\hat p$:

# # Fit # from scipy.optimize import curve_fit p_hat, p_cov = curve_fit(calc_y_change_percent, X, y_change_pct) print('Estimated p:', p_hat) # # Visualise # f, ax = plt.subplots(figsize=(5, 4), layout='tight') ax.set( xlabel='$x_0$', ylabel='$x_1$', title= '$x_0$ and $x_1$ pairs coloured by $\Delta y\%$' + '\n$p_{true}=$' + str(p_true) + '\n$\hat p=$' + str(p_hat.round(4).item()) ) m = ax.scatter(x0, x1, c=y_change_pct) f.colorbar(mappable=m, label='$\Delta y \%$') 
$\endgroup$
2
  • 1
    $\begingroup$ Thanks a lot. This is (genius) and of great help to me! $\endgroup$ Commented Feb 12 at 22:59
  • $\begingroup$ My pleasure @ychung 👍Glad it was helpful. Feel free to ask if anything needs clarification. $\endgroup$ Commented Feb 13 at 11:05

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.