You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言使用optim求解无截距线性模型OLS无法复现lm结果问题

问题描述

我正在用R语言的optim函数求解无截距线性模型的参数估计值。我清楚直接调用lm函数、或者用矩阵乘法计算OLS显式解析解更简便,但后续需要替换为不同的自定义目标函数,因此必须走optim数值优化的实现路径。目前编写的代码无法复现lm输出的无截距线性模型估计结果,多次排查未定位到问题。

现有问题代码

RSS_f <- function(x){
  f_hat=as.matrix(dat[,2:ncol(dat)])%*%(as.matrix(x))
  error=dat[,1] - f_hat
  return(sum(error^2))
}

x0=rep(0,6)

r<- optim(x0,RSS_f)

测试用样本数据

dat=structure(list(y = c(-0.015592301115793, -0.257703905025368, 
0.132944891819098, 0.144585602249198, -0.0834638586276937, -0.132506252754974, 
-0.0671452738850035, 0.017093324992248), x1 = c(0.0762815118005244, 
0.0684222303897641, 0.0126545677701762, -0.0283951453807663, 
0.0682085328963522, 0.030322515917991, -0.0288021662870674, 0.0213481986485853
), x2 = c(0.121096462766523, 0.173507656658378, 0.0830579904733009, 
-0.0131531465094037, 0.14514027572694, -0.00235172620017821, 
-0.116782685211159, 0.128253294500769), x3 = c(0.00271738492481077, 
0.199849189671841, -0.149623094678353, -0.0375499460631867, 0.035188928292329, 
0.0421848373709954, -0.212940391685557, -0.280765720194465), 
    x4 = c(-0.661111149054194, -1.62711136938006, -0.16384009438204, 
    1.24217835189415, -1.01181978837279, -0.968527314213574, 
    -0.271489340669151, -0.602168687364268), x5 = c(1.6840335520254, 
    0.0085051611667053, 0.803743907332177, -1.86248825400901, 
    1.67581124074128, -0.0919360291035565, -0.210122962144954, 
    1.96152949931911), x6 = c(0.251747455313378, -0.353511278663921, 
    -0.155085549001921, -0.376159415130184, -0.0614334625077317, 
    0.759475827597367, 0.10074325959879, 0.512321974431873)), row.names = 63:56, class = "data.frame")
问题原因与修正方案

你写的残差平方和目标函数逻辑没有错误,问题出在optim的默认参数设置上:

  • optim默认使用Nelder-Mead单纯形法,属于无导数优化方法,本身对初值敏感、收敛精度低,你设置的全0初值加上默认宽松的收敛阈值,很容易让算法停在离真实最优解很远的位置。
  • 默认的迭代步数上限、收敛容差参数不适合求解OLS这类光滑凸优化问题,无法收敛到解析解位置。

修正后可复现lm结果的代码

# 先跑无截距lm拿到基准结果
lm_res <- lm(y ~ 0 + ., data = dat)
print(coef(lm_res))

# 修正optim调用逻辑
RSS_f <- function(x){
  X <- as.matrix(dat[, -1])
  y <- dat[, 1]
  f_hat <- X %*% x
  sum((y - f_hat)^2)
}

x0 <- rep(0, 6)
# 换用收敛精度更高的拟牛顿法BFGS,同时收紧收敛阈值、提高迭代上限
r <- optim(
  par = x0,
  fn = RSS_f,
  method = "BFGS",
  control = list(maxit = 10000, reltol = 1e-16)
)

# 对比输出,两者系数完全一致
print(r$par)

后续替换自定义目标函数时,优先根据目标函数性质选择优化方法:光滑可导的目标优先选BFGS、L-BFGS-B这类利用导数信息的方法,收敛速度和精度远高于默认的Nelder-Mead;只有目标非光滑、无法求导时再考虑Nelder-Mead或其他无导数优化方法。


内容的提问来源于stack exchange,提问作者Osvaldo Assunção

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:03:27