我在R中使用 nloptr ,但是,我想让我的模型更自由,因为最好的解决方案并避免过度拟合。我之前已经描述了我的问题in this question:
nloptr(x0, eval_f, eval_grad_f = NULL, lb = NULL, ub = NULL,
eval_g_ineq = NULL, eval_jac_g_ineq = NULL, eval_g_eq = NULL,
eval_jac_g_eq = NULL, opts = list(), ... )
基本上我有一个非线性问题需要解决。我有一个函数来最小化和一些非线性约束。但我不想使用最好的解决方案,因为它会过度拟合样本数据并给我极端的价值。因此,我想找到N个最佳解决方案,然后选择我想要的解决方案。
所以现在我想知道有没有办法找到 nloptr 在迭代过程中找到的N个最佳解决方案。除了 nloptr ?
之外,还有其他方法吗?答案 0 :(得分:2)
这不是一个真正的答案,而是一个长篇评论,我希望这会有所帮助。
我同意@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依赖于数据,另一种方法是使用相同的评估函数,但是使用数据的bootstrap子样本。每次你得到一个不同的最小值(因为不同的样本)。您可以获得N个这样的解决方案,您可以对它们进行平均或做任何您想要生成非过度拟合的解决方案(现在解决方案不会过度拟合数据,因为每个解决方案都基于数据的不同部分)。
我希望它有所帮助。