这不是一个真正的答案,而是一个很长的评论,我希望这会有所帮助。
我同意@tonytonov 的观点,您应该更好地定义“次佳”和您的一般需求。无论如何,为了获得 N 个不同的解决方案,它们不仅彼此非常接近,我会迭代地运行 nloptr,每次使用稍微不同的目标函数,每次都会增加接近前一个解决方案的惩罚。这是一个例子:
sols = list()
evalf= list(eval_f)
for (i in 1:N) {
sols[i] = nloptr(x0,evalf[[i]],...)
# now creating a new evaluation function which adds a log(distance) penalty to the
# last solution
evalf[[i+1]] = function(x) {evalf[[i]](x)-log(sum((x-sols[i]$solution)^2))}
}
您当然可以考虑不同的惩罚,这个想法是为非常接近现有解决方案添加一个很大的惩罚,但是一旦您离它相对较远(您应该知道,足够远是什么意思-这是特定于上下文的),惩罚相对平坦,因此不会影响原始的最低点。您当然应该检查最后一个解决方案是否存在,并且可能将起点(x0)从一个迭代更改为另一个迭代,但我认为您明白了。
更一般地说,当你试图避免过度拟合时,我会首先考虑为你的 eval 函数添加一个惩罚。例如,回归分析中过拟合的标志是系数的大小,因此通常在确定回归估计时尝试最小化的不是误差平方根(典型的 OLS 方法),而是误差平方根 +系数的总和(以某种方式归一化),这会产生对小系数的偏好,从而降低过度拟合的可能性。
我对你的具体问题知之甚少,但也许你可以想出一些“惩罚”函数,在最小化时减少过度拟合。
如果您的 eval_f 依赖于数据,另一种方法是使用相同的评估函数,但使用数据的引导子样本。每次你得到不同的最小值(因为不同的样本)。你得到 N 个这样的解决方案,你可以对它们进行平均或做任何你想做的事情来生成一个非过度拟合的解决方案(现在解决方案不会过度拟合数据,因为每个解决方案都基于数据的不同部分)。
我希望它有所帮助。