【问题标题】:Anyway to fit this model to these data points?无论如何要使这个模型适合这些数据点?
【发布时间】:2021-11-02 16:19:29
【问题描述】:

我一直在尝试将这些数据点拟合到指数模型y=ae^(px+qx^2)。我需要此模型拟合的原因是由于 Göran Englund 2011 年发表的论文“功能响应的温度依赖性”,他们在其中将模型拟合到数据点上,如其中一张图中所述。我需要将其与我在论文中研究的 ODE 模型进行文献综述时发现的一些数据相匹配。但是,无论我做什么,我都无法使用 curvefit() 函数来拟合它,即使我的猜测 p0 非常接近。下面是我的代码和我的拟合图,当时我只是猜测拟合的参数 a、p 和 q,直到我得到一个非常接近的拟合。

k = 0.00008617
def NormalizeData(data):
    return (data - np.min(data)) / (np.max(data) - np.min(data))

def C_to_A(C):
    return -1/(k*(C+273))

def model(x, a, p,q):
    return a*np.exp(p*x+q*x**2)

# Input data
x = C_to_A(np.array([11, 11, 11,15,15,15,20,20,20,25,25,25,29,29,29]))
y = NormalizeData(np.array([2.048, 1.56, 1.18, 2.6116,2.35,2.1036,2.97, 2.97, 2.97, 2.463,2.05,1.6679,1.825,1.0939,0.534]))
# do the fit with some initial values
popt, pcov = curve_fit(model, x, y, p0=(9.7*10**-139.95, -16, -0.2))

# prepare some data for a plot
xx = np.linspace(-60, 0)
yy = model(xx, *popt)

plt.plot(x, y, 'o', xx, yy)
plt.title('Exponential Fit')
plt.ylim(0,1.1)
plt.xlim(-50,32)
plt.grid()
plt.show()
print(popt)

如果我只是用数据点和我猜到的系数a=9.7*10**-139.95, p=-16, q=-0.2 绘制模型,我会得到下面的图片

这与我想要的非常接近。关于如何使用我提到的模型来接近这种拟合的任何建议?任何事情都会有帮助!

【问题讨论】:

  • 您忘记在代码中定义k
  • @KotaMori 抱歉,这里的 k = 0.00008617。我也编辑了我的帖子。

标签: python curve-fitting curve data-fitting model-fitting


【解决方案1】:

y=ae^(px+qx^2) 表示log(y) = c + px + qx^2,其中c=log(a),p,q 是参数。您可以使用yxx^2 的线性回归来估计参数。

import numpy as np
import pandas as pd
from statsmodels.api import OLS
import matplotlib.pyplot as plt


def C_to_A(C, k=0.00008617):
    return -1/(k*(C+273))

# choice of k is arbitrary, change as you wish
x = C_to_A(np.array([11, 11, 11,15,15,15,20,20,20,25,25,25,29,29,29]), k=1)
y = np.array([2.048, 1.56, 1.18, 2.6116,2.35,2.1036,2.97, 2.97, 2.97, 2.463,2.05,1.6679,1.825,1.0939,0.534])


# want to regress log(y) on x, x^2, constant
# create data for this
data = pd.DataFrame({"y":y, "x":x})
data["log_y"] = np.log(data.y)
data["x2"] = data.x**2
data["const"] = 1
data

使用来自 statsmodels 的 OLS 估计参数:

Y = data.log_y
X = data[["x", "x2", "const"]]

ols = OLS(Y, X, hasconst=True).fit()
ols.summary()

对于绘图,ols 的拟合值属性很方便。我们使用 exp 将 log(y) 转换为 y:

plt.scatter(x, y)
plt.plot(x, np.exp(ols.fittedvalues))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 2021-05-08
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多