无法使用 scipy.optimize.curve_fit 拟合函数

问题描述

我目前正在尝试评估我的一些数据并尝试复制此处描述的拟合函数https://www.graphpad.com/guides/prism/latest/curve-fitting/reg_classic_dr_variable.htm

起初我遇到了 numpy.float_power 溢出的问题,但我想我已经解决了(我真的解决了吗?)。

我现在正在使用 scipy.optimize.curve_fit 将描述的 sigmoid 拟合到我的数据中,但它实际上似乎从未拟合过,而是产生了常数函数,我不知道为什么。

这是我的代码


import numpy as np
import matplotlib.pyplot as plt

'''
Just a method that produces some simple test data
'''
def test_data_1():
    return np.array([[0.000610352,0.002441406,0.009765625,0.0390625,0.15625,0.625,2.5,10],[0.89,0.81,0.64,0.48,0.45,0.50,0.58,0.70]])

'''
Just a simple method that produces some more test data
'''
def test_data_2():
    return np.array([[0.000610352,[1,0.83,0.68,0.52,0.59,0.75,0.62]])

'''
Dose response curve as described in: https://www.graPHPad.com/guides/prism/latest/curve-fitting/reg_classic_dr_variable.htm
'''
def sigmoidal_dose_response_with_variable_slope(x_data,*params):
    # Extract relevant parameters. Flattening the array just in case?
    r_params = np.array(params).flatten()
    bottom = r_params[0]
    top = r_params[1]
    logec50 = r_params[2]
    slope = r_params[3]

    # Calculating the numerator
    numerator = top - bottom
    # Calculating the denominator
    denominator = 1 + np.float_power(10,(logec50 - x_data) * slope,dtype=np.longdouble)
    return np.array(bottom + (numerator / denominator),dtype=np.float64)

if __name__ == "__main__":

    x_data,y_data = test_data_1()

    # Guessing bottom and top as the highest and lowest y-values.
    bottom_guess = np.min(y_data)
    bottom_guess_idx = np.argmin(y_data)
    top_guess = np.max(y_data)
    top_guess_idx = np.argmax(y_data)

    # Guessing logec50 as the middle between those parameters
    logec50_guess = np.linalg.norm(x_data[top_guess_idx] - x_data[bottom_guess_idx]) / 2 \
                    + np.min([x_data[top_guess_idx],x_data[bottom_guess_idx]])

    # Guessing a slope of 1
    slope_guess = 1
    p0 = [bottom_guess,top_guess,logec50_guess,slope_guess]

    # Fitting the curve to my data
    popt,pcov = curve_fit(sigmoidal_dose_response_with_variable_slope,x_data,y_data,p0)

    # Making the x-axis scale logarithmically
    fig,ax = plt.subplots()
    ax.set_xscale('log')

    # Plot my data
    plt.plot(x_data,'s')

    # Calculate function data. The borders are merely a guess
    x_val = np.linspace(0,10,100)
    y_val = sigmoidal_dose_response_with_variable_slope(x_val,popt)

    # Plot
    plt.plot(x_val,y_val)
    plt.show()

它应该易于测试。

更新: 像这样的东西就是我正在寻找的:

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)