如何避免curve_fit对单个数据点过拟合?
如何避免curve_fit对单个数据点过拟合?
嘿,我之前用curve_fit的时候也遇到过这种被单个点“带偏”的情况,太闹心了!给你几个不用写太多额外代码的办法,都是curve_fit本身支持的:
用稳健损失函数(推荐!)
从scipy 1.7.0版本开始,curve_fit新增了loss参数,专门用来处理这种对异常点敏感的情况。你不用手动算权重,只要把损失函数换成对大误差不那么敏感的类型就行,比如'huber'或者'soft_l1'。举个例子:from scipy.optimize import curve_fit import numpy as np def my_func(x, C, D): a = 10 # 替换成你已知的a值 return C * np.sqrt(a - x) + D # 假设x_data、y_data是你的数据集 popt, pcov = curve_fit(my_func, x_data, y_data, loss='huber')Huber损失会在误差较小时用平方误差(和普通拟合逻辑一致),当误差大到某个阈值后自动切换成线性误差,这样单个点的极端误差就不会把整体拟合结果拽偏了。
给参数加合理范围约束
如果你大概知道C和D的合理取值区间,用bounds参数给它们设个上下限,就能防止参数被那个“捣乱”的点拉到离谱的数值。比如你知道C应该在0到15之间,D在3到22之间:popt, pcov = curve_fit(my_func, x_data, y_data, bounds=((0, 3), (15, 22)))这样哪怕单个点想把参数拽出合理范围,curve_fit也会强制把参数限制在你设定的区间里。
微调疑似异常点的相对权重
虽然你说所有数据的不确定度相同,但如果那个点看起来确实像是个离群值,你可以给它的sigma设大一点(相当于降低它的拟合权重)。curve_fit的sigma参数如果是数组,会自动把每个点的权重设为1/sigma²。比如假设那个问题点是第6个(索引为5):sigma = np.ones_like(y_data) # 所有点初始sigma设为1 sigma[5] = 4 # 放大该点的sigma,降低它的权重占比 popt, pcov = curve_fit(my_func, x_data, y_data, sigma=sigma, absolute_sigma=False)这里
absolute_sigma=False很关键,它告诉curve_fit sigma只是用来做相对加权,不用严格对应实际的测量不确定度。
你可以先试试第一个方法,代码改动最小,效果还很直接!
备注:内容来源于stack exchange,提问作者nhal
相关产品推荐
相关产品推荐

