Python中拟合Logistic函数却得到直线的问题求助
为什么拟合Logistic函数得到直线?
核心原因有两个:
1. 数据和Logistic函数的特征不匹配
Logistic函数是单调递增/递减的S型曲线,最终会趋近两个固定的饱和值,但你的y值是104→103→95→79→83,呈现先降后小幅回升的非单调趋势,完全不符合Logistic的形态,强行拟合自然得不到预期的S型结果。
2. 默认初始参数导致拟合陷入局部最优
curve_fit默认所有参数初始值为1,这个初始状态离Logistic函数的合理参数范围太远,容易让拟合过程收敛到局部最优解。比如当参数c被拟合到接近0时,np.exp(-c*(x-d))趋近于1,函数就变成a/(1+1)+b,也就是一条水平直线;如果c极小,函数变化极慢,看起来也近似直线。
解决办法
换用更匹配的函数:如果数据是先降后升,优先考虑二次函数(
y = ax² + bx + c)这类非单调曲线模型,更贴合数据趋势。手动指定初始参数(非要用Logistic的话):根据数据范围给参数一个合理的初始值,引导拟合找到正确方向:
a:曲线振幅(y的最大值减最小值),你的y范围是79-104,设为25左右;b:曲线下限值,设为79左右;c:控制曲线陡峭程度,设为0.01这类小非零值;d:曲线拐点对应的x值,你的x中点是573,设为573。
修改后的代码示例:
import numpy as np from scipy import optimize as opt import matplotlib.pyplot as plt x = [473,523,573,623,673] y = [104,103,95,79,83] x = np.array(x) y = np.array(y) def f(x,a,b,c,d): return a/(1+np.exp(-c*(x-d))) + b # 手动设置初始参数 initial_guess = [25, 79, 0.01, 573] popt, pcov = opt.curve_fit(f, x, y, method="trf", p0=initial_guess) y_fit = f(x,*popt) plt.plot(x,y,'o') plt.plot(x,y_fit,'-') plt.show()注意:即使这样,因为数据本身不是S型,拟合结果也不会完美贴合数据,只是不会输出直线。
内容的提问来源于stack exchange,提问作者Krishh
相关产品推荐
相关产品推荐

