Python中拟合双曲余弦单峰曲线遇问题求助
双曲余弦单峰(谷型)曲线拟合问题排查与修正
问题根源
你当前的拟合失败主要有两个核心问题:
- 模型形式错误:你用的
a * np.cosh(x/b) + c是开口向上的U型曲线,但你的数据呈现的是中间低、两端高的倒U型(谷型),模型的凹凸性和数据完全相反。 - 初始参数不合理:
p0的取值没有贴合模型和数据特征,导致curve_fit无法找到最优解。
修正方案
1. 调整双曲余弦模型
需要使用开口向下的双曲余弦模型,同时加入x轴偏移量x0(控制谷的位置),修正后的模型为:
def model_hcosine(x, a, b, x0, c): return -a * np.cosh((x - x0)/b) + c
-a:让曲线开口向下,匹配数据的谷型x0:控制谷在x轴上的位置,对应数据中y最小的点(x≈35)b:控制曲线的陡峭程度c:控制曲线的基线高度(对应数据两端的峰值)
2. 设置合理的初始参数p0
根据数据特征设置初始值:
a:取两端峰值与谷值的差,比如max(yData) - min(yData)≈26b:取x范围的一半,比如(max(xData)-min(xData))/2≈34x0:取y最小对应的x值,即35c:取数据的峰值,即30
完整修正代码
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit xData = np.array([1.7, 8.8, 15, 25, 35, 45, 54.8, 60, 64.7, 70]) yData = np.array([30, 20, 13.2, 6.2, 3.9, 5.2, 10, 14.8, 20, 27.5]) # 修正后的谷型双曲余弦模型 def model_hcosine(x, a, b, x0, c): return -a * np.cosh((x - x0)/b) + c # 设置贴合数据特征的初始参数 p0 = [max(yData)-min(yData), (max(xData)-min(xData))/2, 35, max(yData)] poptcosh, pcovcosh = curve_fit(model_hcosine, xData, yData, p0=p0) a_opt, b_opt, x0_opt, c_opt = poptcosh xCoshModel = np.linspace(min(xData), max(xData), 100) yCoshModel = model_hcosine(xCoshModel, a_opt, b_opt, x0_opt, c_opt) plt.scatter(xData, yData, label='原始数据') plt.plot(xCoshModel, yCoshModel, 'b-', label='拟合曲线') plt.legend() plt.show()
效果说明
运行修正后的代码,拟合曲线会完美贴合你的数据特征:中间在x≈35处形成谷,两端逐渐上升至峰值,和原始数据的趋势完全匹配。
内容的提问来源于stack exchange,提问作者Nob
相关产品推荐
相关产品推荐

