Python指数曲线拟合时While True循环卡顿问题求助
指数拟合迭代卡顿问题:自定义最小二乘法+随机试错法的缺陷
我自己实现曲线拟合函数,用最小二乘法处理多项式、对数拟合都正常,但指数拟合效果极差,对比下来scipy的curve_fit效果要好得多。于是我改成先用最小二乘法算出a、b的初始值,再用随机试错的迭代方式优化参数,结果现在出现循环迭代耗时越来越长,最终直接卡死的问题。
自定义拟合相关函数
import numpy as np def exp_func(x,i,a,b): return a*np.exp(b*x[i]) def error_function(x,y,i,a,b): approximation = exp_func(x,i,a,b) residual = (abs(y[i]-approximation))/y[i] return residual
核心拟合函数
def curve_fit(data,x,type,degree=None): if type == 'exp': A = np.ones((len(data),2)) for i in range(0,len(data)): A[i,1] = x[i] data = np.log(data) data = np.transpose(data) y = np.linalg.inv(np.transpose(A)@A)@(np.transpose(A)@data) y[0] = np.exp(y[0]) data = np.exp(data) data = np.transpose(data) learning_rate = 1 tolerance = 0.5 previous_error = (sum(error_function(x,data,i,y[0],y[1]) for i in range(0,len(data)))) new_error = (sum(error_function(x,data,i,y[0],y[1]) for i in range(0,len(data)))) while True: if new_error < tolerance: break y_0new = y[0] + learning_rate*(np.random.uniform(-1,1)) y_1new = y[1] + learning_rate*(np.random.uniform(-1,1)) new_error = (sum(error_function(x,data,i,y_0new,y_1new) for i in range(0,len(data)))) if new_error < previous_error: y[0] = y_0new y[1] = y_1new previous_error = new_error return y
测试代码
import matplotlib.pyplot as plt x = np.linspace(0,5,20) # 测试用例 test1 = np.array([1,10,25,40,50]) t1 = np.arange(1,6) a,b = curve_fit(test1,t1,'exp') fig, ax = plt.subplots() plt.grid() plt.plot(t1,test1,marker='o',ms=5,linestyle='') plt.plot(x,a*np.exp(b*x),color='black') plt.show()
问题根源分析
- 随机试错效率极低:每次仅通过随机数调整参数,大概率无法找到更优解,导致循环无限迭代无法终止
- 学习率设置不合理:
learning_rate=1过大,参数波动范围太广,容易跳过最优区域,甚至导致误差发散 - 终止条件不完善:仅依赖误差小于
tolerance,但当随机优化无法找到更优解时,循环会一直尝试随机参数,最终卡死 - 初始值偏差:对数变换后的最小二乘法本身会引入系统偏差(尤其数据存在噪声时),后续原始的随机优化无法有效修正
内容的提问来源于stack exchange,提问作者Giovanni Paiela
相关产品推荐
相关产品推荐

