如何用Python提升误差函数拟合质量?目标R²>0.99
误差函数拟合优化:目标R²>0.99
我正在对lenJ1数据集进行误差函数拟合,但拟合曲线效果不佳,希望优化拟合质量使R²值大于0.99。
现有实现代码
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit from sklearn.metrics import r2_score # Define the error function def error_function(x, a, b, c, d): return a + b * np.exp(-(x - c)**2 / (2.0 * d**2)) # Data lenJ1 = [337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 336, 336, 334, 334, 333, 331, 331, 331, 329, 329, 328, 324, 323, 315, 308, 294, 283, 273, 264, 244, 234, 222, 217, 205, 188, 181, 174, 162, 151, 133, 126, 117, 112, 105, 96, 95, 87, 80, 73, 62, 59, 58, 52, 40, 35, 33, 31, 30, 29, 29, 26, 23, 21, 19, 18, 16, 15, 15, 15, 15, 15, 15, 14, 13, 12, 12, 12, 12, 12, 11, 10, 8, 8, 7, 7, 7, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0] lenJ1 = [1 - (i / 1012) for i in lenJ1] t_start = 0.0 t_end = 1e2 timesteps = int(1e3 * t_end) + 1 t1 = np.linspace(t_start, t_end, timesteps) print(timesteps) # Provide adjusted initial guesses for parameters based on the data characteristics initial_guess = [1, 1, 1, 1] # Fit the error function to the data with adjusted initial guesses popt, pcov = curve_fit(error_function, t1[:len(lenJ1)]/1.0330677596203013, lenJ1, p0=initial_guess, bounds=([0, 0, 0, 0], [100, 100, 100, 100])) # Predicted values using the fitted curve predicted_values = error_function(t1[:len(lenJ1)]/1.0330677596203013, *popt) # Calculate R^2 value r_squared = r2_score(lenJ1, predicted_values) # Plot the data and the fitted curve plt.plot(t1[:len(lenJ1)], lenJ1, 'b-', label='Data') plt.plot(t1[:len(lenJ1)], error_function(t1[:len(lenJ1)]/1.0330677596203013, *popt), 'r--', label='Fitted Curve') plt.xlabel('t1') plt.ylabel('Values') plt.title('Error Function Fit') plt.legend() plt.show() # Print the parameters of the fitted error function print("Parameters (a, b, c, d):", popt) print("R^2 value:", r_squared)
当前拟合结果

优化方案及修改后代码
核心优化点
- 精准初始参数猜测:根据数据趋势调整初始值,匹配误差函数的物理意义:
a:数据最终渐近值(接近0)b:初始值与渐近值的差值(≈0.67,由1-337/1012计算得出)c:数据开始下降的中心位置(≈0.03,对应前27个稳定点的结束位置)d:控制下降速度的宽度参数(≈0.05)
- 缩小参数边界:根据数据范围限制参数搜索区间,避免拟合陷入局部最优
- 增加迭代次数:设置
maxfev=10000,确保拟合有足够次数收敛
修改后代码
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit from sklearn.metrics import r2_score # Define the error function def error_function(x, a, b, c, d): return a + b * np.exp(-(x - c)**2 / (2.0 * d**2)) # Data lenJ1 = [337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 336, 336, 334, 334, 333, 331, 331, 331, 329, 329, 328, 324, 323, 315, 308, 294, 283, 273, 264, 244, 234, 222, 217, 205, 188, 181, 174, 162, 151, 133, 126, 117, 112, 105, 96, 95, 87, 80, 73, 62, 59, 58, 52, 40, 35, 33, 31, 30, 29, 29, 26, 23, 21, 19, 18, 16, 15, 15, 15, 15, 15, 15, 14, 13, 12, 12, 12, 12, 12, 11, 10, 8, 8, 7, 7, 7, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0] lenJ1 = [1 - (i / 1012) for i in lenJ1] t_start = 0.0 t_end = 1e2 timesteps = int(1e3 * t_end) + 1 t1 = np.linspace(t_start, t_end, timesteps) print(timesteps) # 基于数据特征的精准初始猜测 initial_guess = [0.01, 0.67, 0.03, 0.05] # 缩小参数边界,匹配数据范围 lower_bounds = [0, 0, 0, 0.01] upper_bounds = [0.1, 0.7, 0.1, 0.2] # 拟合时增加迭代次数,确保收敛 popt, pcov = curve_fit( error_function, t1[:len(lenJ1)]/1.0330677596203013, lenJ1, p0=initial_guess, bounds=(lower_bounds, upper_bounds), maxfev=10000 ) # 计算预测值与R² predicted_values = error_function(t1[:len(lenJ1)]/1.0330677596203013, *popt) r_squared = r2_score(lenJ1, predicted_values) # 绘图 plt.plot(t1[:len(lenJ1)], lenJ1, 'b-', label='Data') plt.plot(t1[:len(lenJ1)], predicted_values, 'r--', label='Fitted Curve') plt.xlabel('t1') plt.ylabel('Values') plt.title('Optimized Error Function Fit') plt.legend() plt.show() # 输出结果 print("Parameters (a, b, c, d):", popt) print("R^2 value:", r_squared)
内容的提问来源于stack exchange,提问作者user23495528
相关产品推荐
相关产品推荐

