无约束非线性优化报错:NLOPT_INVALID_ARGS问题排查求助
问题排查与解决方案
核心报错原因:未指定参数上下界
NLOPT_GN_ISRES 是基于进化策略的全局优化算法,必须明确指定参数的搜索上下界(lb 和 ub 参数),哪怕是无约束问题也需要定义合理的搜索范围,否则会触发 NLOPT_INVALID_ARGS 错误。你的代码中仅提供了初始值 x0,未设置上下界,这是直接报错的原因。
其他需要修正的问题
目标函数方向问题
nloptr 默认是最小化目标函数,但你的需求是最大化F1分数,因此需要返回-F1让算法朝着最大化原目标的方向优化:# 修改返回语句 f1_score <- 2*(TP/(TP+FP))*(TP/(TP+FN)) / ((TP/(TP+FP))+(TP/(TP+FN))) return(-f1_score)参数类型合理性
lagg是滞后阶数,应为正整数,但NLOPT_GN_ISRES是连续优化算法。可以先设定整数范围的上下界(比如lb[1]=1,ub[1]=24,根据你的时间序列长度调整),后续再对优化结果取整,或者改用支持整数优化的算法。
修正后的代码示例
fxn_unsmoothed2 <- function(input) { lagg <- input[1] thres <- input[2] truth <- data.matrix(USREC[-1:-lagg,]) chng <- percentchange(goodsmtx, lagg) chng[chng < thres] <- 1 chng[chng != 1] <- 0 FP <- length(which(chng == 1 & truth == 0)) FN <- length(which(chng == 0 & truth == 1)) TP <- length(which(chng == 1 & truth == 1)) TN <- length(which(chng == 0 & truth == 0)) # 计算F1并取负数用于最小化 f1_score <- 2*(TP/(TP+FP))*(TP/(TP+FN)) / ((TP/(TP+FP))+(TP/(TP+FN))) return(-f1_score) } x0 <- c(11, 0.005) # 指定上下界:lagg范围1-24,thres根据数据范围设定(比如-0.1到0.1) lb <- c(1, -0.1) ub <- c(24, 0.1) opts <- list("algorithm"="NLOPT_GN_ISRES", maxeval=100000) res <- nloptr( x0 = x0, eval_f = fxn_unsmoothed2, lb = lb, ub = ub, opts = opts ) # 查看结果,注意要把返回的负数转回来得到最大F1 max_f1 <- -res$objective optimal_params <- res$solution
额外注意事项
- 确保
percentchange函数能正确处理lagg参数,避免因滞后阶数超出时间序列长度导致的索引错误。 - 如果需要严格整数的
lagg,可以在优化后对optimal_params[1]取整,或者改用支持整数变量的优化算法。
内容的提问来源于stack exchange,提问作者jlewis
相关产品推荐
相关产品推荐

