What is the best method of estimating a ratio of regression coefficients $\beta_1/\beta_2$ under the usual assumptions / in practice? I have two relatively well approximated signals $X_1, X_2$ and they have been multiplied by unknown coefficients $\beta_1, \beta_2$. Then the output has been drenched in other noise signals with relatively normal and zero mean distributions, thus yielding the standard regression model, where $Y$ is the observed data
$$Y=\beta_1X_1+\beta_2X_2+\epsilon.$$
Estimating the ratio by standard OLS is not straight forward, since (assuming independence - which should not be assumed in general) $$\mathbb{E}(\hat \beta_1/\hat \beta_2) =\mathbb{E}(\hat \beta_1)\mathbb{E}({\frac{1}{\hat \beta_2}})=\infty,$$ showing that the trivial estimator of using the ratio of OLS estimates $\hat \beta_1/\hat \beta_2$ is biased when estimating $\beta_1 /\beta_2 = \mathbb{E}(\hat \beta_1)/\mathbb{E}(\hat \beta_2)$. The last equality is due to the infinite variance of the reciprocal normal distribution.
What is an unbiased and the most efficient way of estimating the ratio? Is there a source for rigorously developed estimators for the scenario? Particularly I am interested in obtaining as sharp CI as possible.
Below is a straight forward code for trying different estimators. Decreasing the frequency difference between the sinusoids 1600, 1623
makes the problem more difficult and increases the bias. Note that the toy example may not generalize to more complicated scenarios, but functions as a useful work bench.
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
def ratioestimator(beta1=0.5, beta2=1.0, N=40000, n=500):
b_strap=np.zeros(N)
t=np.arange(0,n)
X1=np.sin(t*2*np.pi/44100*1600)
X2=np.sin(t*2*np.pi/44100*1623)
for i in range(N):
eps = np.random.normal(0,3,n)
Y=X1*beta1+X2*beta2+eps
#ESTIMATOR AND ESTIMATES:
M = sm.OLS(Y, np.column_stack((np.ones(len(X1)),X1,X2))).fit()
b_strap[i]=M.params[1]/M.params[2]
#//ESTIMATOR AND ESTIMATES
# Analysis:
bins=np.arange(0,1,0.05)
plt.hist(b_strap,bins=bins)
print("Mean of estimates: ", np.mean(b_strap))
print("Median of estimates: ", np.median(b_strap))
print("10% CI of estimates:", np.percentile(b_strap,45),np.percentile(b_strap,55))
print("50% CI of estimates:", np.percentile(b_strap,25),np.percentile(b_strap,75))
print("80% CI of estimates:", np.percentile(b_strap,10),np.percentile(b_strap,90))
print("95% CI of estimates:", np.percentile(b_strap,2.5),np.percentile(b_strap,97.5))
ratioestimator()