【发布时间】:2021-11-02 16:10:06
【问题描述】:
我有以下功能,我需要使用最小二乘法来最小化(我正在使用 lmfit)。
y = a * exp(-x/b) + c
我有例如以下数据:
profitlist = [-10000, 100.00, 1000.00, 100000.00, 1000000.00]
utilitylist = [0, 0.2, 0.4, 0.6, 1]
应用返回以下错误:
ValueError: NaN values detected in your input data or the output of your objective/model function - fitting algorithms cannot handle this! Please read https://lmfit.github.io/lmfit-py/faq.html#i-get-errors-from-nan-in-my-fit-what-can-i-do for more information.
问题似乎是:如果 ProfitList 包含任何更大的负数 ( -1000 有效,-100000 无效)。所以它可能会溢出。
profitList 中的值可以是非常大的浮点数,而且它们并不总是相同的。那么如何用这些巨大的数字来优化它呢?似乎 lmfit 不支持可以解决问题的十进制数字......我该怎么做才能让它工作?
class LeastSquares:
def __init__(self, profitList, utilityList):
self.profitList = np.asarray(profitList)
self.utilityList = np.asanyarray(utilityList)
def function(self, params, x):
a = params["a"]
b = params["b"]
c = params["c"]
return a * np.exp(-x/b) + c
def residual(self, params, x, y):
return (y - self.function(params, x))**2
def setParameters(self, a_start, b_start, c_start):
parameters = Parameters()
parameters.add(name="a", value=a_start, min=None, max=0, vary=True)
parameters.add(name="b", value=b_start, vary=True, min=0.1, max=None)
parameters.add(name="c", value=c_start, vary=True)
return parameters
def startOptimalization(self):
parameters = self.setParameters(-1, 1, 1)
result = minimize(self.residual, parameters, args=(self.profitList, self.utilityList), method="leastsq")
result.params.pretty_print()
print(fit_report(result))
print("SSE")
print(np.sum(result.residual))
【问题讨论】:
-
为什么不切换
profitlist中的单位以使其与utilitylist中的数字更具可比性?否则,我会怀疑任何答案的数值稳定性。 -
@JohnColeman 我该怎么做?如果我将利润列表中的所有数字除以 1 000 000 比我认为的结果不一样?
-
如果您不信任他们,为什么要获得相同的结果?无论如何,以百万美元来衡量利润是很常见的。您还可以探索诸如将
utilitylist中的数字乘以 100 的动作,这样单位就是百分比。 -
尝试使用更大的值作为参数
b的初始猜测值。