I'm trying to fit a two-parameter function to data that looks like this (black dots, x scale is logarithmic):
The best fit I could find is an $arctan$, measured by the MSE. All the seven functions I tested and the Python code are shown below.
Is there perhaps a better function to fit this data that I might have overlooked?
import numpy as np
import matplotlib.pyplot as plt
def main():
x = np.array([0.033, 0.062, 0.104, 0.210, 0.424, 0.861, 1.040, 1.133, 1.935, 3.803, 6.289, 11.519, 29.118])
y = np.array([
0.077, 0.149, 0.187, 0.229, 0.299, 0.419, 0.469, 0.499, 0.679, 0.806,
0.888, 0.928, 0.956])
N = 100
for i, func in enumerate((f1, f2, f3, f4, f5, f6, f7)):
beta_opt, alpha_opt, delta_old = np.nan, np.nan, np.inf
for alpha in np.linspace(0., 2, N):
for beta in np.linspace(0., 5, N):
y_fit = func(x, alpha, beta)
delta = np.square(y - y_fit).sum()
if delta < delta_old:
beta_opt, alpha_opt = beta, alpha
delta_old = delta
x0 = np.linspace(0.01, 30, 100)
y0 = func(x0, alpha_opt, beta_opt)
plt.plot(
x0, y0, ls=':', lw=2,
label="f{}, alpha={:.3f}, beta={:.3f}, MSE={:.3f}".format(i+1, alpha_opt, beta_opt, delta_old))
plt.scatter(x, y, c='k')
plt.xscale('log')
plt.legend()
plt.show()
def f1(x, alpha, beta):
return alpha + beta*np.log(x)
def f2(x, alpha, beta):
return alphanp.tanh(xbeta)
def f3(x, alpha, beta):
return alpha + beta*np.tanh(x)
def f4(x, alpha, beta):
return 1/(alpha+beta*np.exp(-x))
def f5(x, alpha, beta):
return alpha + 1/(1+beta*np.exp(-x))
def f6(x, alpha, beta):
return alpha - np.exp(-beta*x)
def f7(x, alpha, beta):
return alpha + beta*np.arctan(x)
if name == 'main':
main()


